This code compiles fine on Clang and Visual C++ but not on GCC:
#include <iostream>
template <class T>
struct Test {
Test(T &t) : _t(t) {
}
void method() {
std::cout << _t.Internal::_value << "\n"; // Doesn't work on GCC
std::cout << _t.T::Internal::_value << "\n"; // Work on all compilers
}
private:
T &_t;
};
template <class T>
struct Base {
T _value = 1;
};
template <class T>
struct Child : Base<int> {
using Internal = Base<int>;
int _value = 2;
};
int main(int argc, const char * argv[]) {
Child<float> child;
Test<Child<float>> test(child);
test.method();
return 0;
}
The error message from GCC is
error: 'Internal' has not been declared
9 | std::cout << _t.Internal::_value << "\n";
| ^~~~~~~~
Which one is right ?
Visual C++ and Clang are right in accepting this code.
It was a bug in GCC that prevented it from doing the same. The error as in the question was up to GCC 10, in GCC 11 its wording changed to
And GCC trunk finally accepts the code as well. Demo: https://gcc.godbolt.org/z/dj34Yhns3
So we could expect the fix in GCC 12.