未使用的模板方法出错

时间:2013-07-11 16:26:14

标签: c++ templates gcc clang non-static

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

1 个答案:

答案 0 :(得分:5)

您的程序不正确,并且两个编译器都是正确的,因为标准不需要符合编译器的诊断(让gcc忽略它)。没有有效实例化的模板(标准术语中的专门化)是不正确的,即使该模板从未实例化。

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

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

  

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