未使用的模板方法中出错

error in unused template method

本文关键字:出错 模板方法 未使用      更新时间:2023-10-16
struct B
{
    int a;
    void foo() {a = 5;}
};
template <typename T>
struct A
{
    A(int i) { B::foo(); }
    A(double d) {}
};
int main()
{
    A<int> a(5.0);
}

GCC 4.7.2 编译它没有错误。Clang 3.4svn 抱怨:

$ clang -Wall -Wextra test.cpp 
test.cpp:10:16: error: call to non-static member function without an object argument
        A(int i) { B::foo(); }
                   ~~~^~~

代码当然是错误的,但是哪个编译器符合标准?

同样奇怪的是,如果您使用 5 而不是 5.0,clang 不会像 gcc 那样打印任何"实例化"注释:

$ gcc test.cpp 
test.cpp: In instantiation of ‘A<T>::A(int) [with T = int]’:
test.cpp:15:12:   required from here
test.cpp:9:13: error: cannot call member function ‘void B::foo()’ without object

你的程序不正确,两个编译器都是正确的,因为标准不需要来自符合要求的编译器的诊断(让 gcc 忽略它(。不能有有效实例化的模板(标准术语中的专用化(是不正确的,即使该模板从未实例化也是如此。

在您的情况下,A<T>::A(int)B::foo()的名称是一个非依赖名称,因此需要在第一阶段查找期间解析它,并且它只能引用上面定义的B类。因为它不是static成员函数,而是非静态函数,所以无论用于实例化A<T>模板的类型T代码都是不正确的,并且程序格式不正确。

相关引用来自 14.6 [temp.res]/8:

知道哪些名称是类型名称可以检查每个模板定义的语法。不得对可生成有效专用化的模板定义发出诊断。如果无法为模板定义生成有效的专用化,并且未实例化该模板,则模板定义格式不正确,无需诊断。