Tuesday 22 March 2016

c++ - Is template qualifier required in class template non-dependent member variables?



I got the compile error "error: use 'template' keyword to treat 'foo' as a dependent template name" when I compile the following code on commented line. (test4)



All other parts of codes are successfully compiled.



#include 

struct my {
template
void foo() {}
};

void test1() {
my m;
auto tr = std::forward_as_tuple(m);
auto& t0 = std::get<0>(tr);
t0.foo();
}

template
struct test2 {
void method() {
my m;
auto tr = std::forward_as_tuple(m);
auto& t0 = std::get<0>(tr);
t0.foo();
}
};

template
struct test3 {
void method() {
m.foo();
}
my m;
};

template
struct test4 {
void method() {
auto tr = std::forward_as_tuple(m);
auto& t0 = std::get<0>(tr);
t0.foo(); // error: use 'template' keyword to treat 'foo' as a dependent template name
t0.template foo(); // OK
}
my m;
};

template
struct test5 {
void method() {
std::tuple tr = std::forward_as_tuple(m);
auto& t0 = std::get<0>(tr);
t0.foo();
}
my m;
};

template
struct test6 {
void method() {
auto tr = std::forward_as_tuple(m);
my& t0 = std::get<0>(tr);
t0.foo();
}
my m;
};


int main() {
test1();
test2().method();
test3().method();
test4().method();
test5().method();
test6().method();
}


test4 is a class template but m is non dependent type.



I tried to compile gcc and clang. gcc 7.1.0 dosen't report errors, but clang 4.0 and later report the compile error.



Error



https://wandbox.org/permlink/HTSBJMD2kXwfWObl (clang 4.0)
https://wandbox.org/permlink/BcUT8gtaFxwC41c5 (clang HEAD)



No error



https://wandbox.org/permlink/GjIvZa3i5HB8uh6w (gcc 7.1.0)



Which is correct behavior?


Answer



I'm going to agree with your suspicion. This is indeed a clang bug.



The template is required if and only if t0 is a dependent name. In particular, it's required if t0 depends on T. And that's the T in test4.



Now, t0 depends on my m, and there's a my::foo, but that's an unrelated T in a different scope. Additionally, t0 doesn't depend on my::foo.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...