Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which compiler is right? 'template' before templated return type needed?

This snippet (taken from this question) compiles fine with g++ (as seen), so long the template before the return type is there. In contrast, VC10 does not compile that code with the following error:

error C2244: 'A::getAttr' : unable to match function definition to an existing declaration

If I remove the template, VC10 is happy but g++ screams this error:

error: non-template 'AttributeType' used as template
note: use 'A::template AttributeType' to indicate that it is a template

Is it again because of VC's broken two-phase look-up or what is the cause? Which compiler is right here? I suspect g++ to be correct, as I have a vague memory of template being needed here, like with the rebind template inside of allocators.


Edit: We have a winner: g++/GCC (surprise surprise...).


template <typename T, typename K>
class A {
public:
    T t;
    K k;

    template <int i, int unused = 0>
    struct AttributeType{
    };

    template <int i>
    AttributeType<i> getAttr();

};

template <typename T, typename K>
template <int i>
typename A<T, K>::template AttributeType<i> A<T, K>::getAttr() {
//                ^^^^^^^^ -- needed or not?
    return t;
}


int main(){
    A<int,int> a;
}
like image 360
Xeo Avatar asked Jun 03 '11 20:06

Xeo


1 Answers

GCC is right. AttributeType is a dependent template-name which is followed by angle bracket <, so the keyword template is required here to remove the ambiguity1, making it clear to the compiler that what is followed is a template-name. The rule is mentioned in §14.2/4:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

1 @Johannes has written a very good explanation here:

Where and why do I have to put the "template" and "typename" keywords?

like image 77
Nawaz Avatar answered Oct 20 '22 06:10

Nawaz