Question

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 compiles it without errors. clang 3.4svn complains:

$ 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(); }
                   ~~~^~~

Of course the code is wrong, but which compiler is conformant with the standard?

It's also strange that clang doesn't print any 'in instantiation' note like gcc does if you use 5 instead of 5.0:

$ 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
Was it helpful?

Solution

Your program is incorrect, and both compilers are right as the standard does not require a diagnostic from a conforming compiler (letting gcc ignore it). A template for which there can be no valid instantiation (specialization in standard jargon) is incorrect even if that template is never instantiated.

In your case, the name B::foo() inside A<T>::A(int) is a non-dependent name, so it needs to be resolved during the first phase lookup, and it can only refer to the B class defined above. Because it is not a static member function, but a non-static one, the code is incorrect, regardless of the type T used to instantiate the A<T> template and the program is ill-formed.

The relevant quote is from 14.6 [temp.res]/8:

Knowing which names are type names allows the syntax of every template definition to be checked. No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top