Here is a program I am trying to compile.
template <typename T>
struct A
{
T foo() const
{
return 1;
}
};
template <typename T>
struct B : A<T>
{
using U = A<T>;
T foo() const
{
return 2;
}
};
template <typename T>
struct D
{
B<T> b;
int foo() const
{
// using U = typename B<T>::U; // compilation succeeds if I uncomment this line
return b.U::foo();
}
};
int main()
{
D<int> d;
return d.foo();
}
I see different behaviour across gcc 9.2, clang 9.0.0 and icc19.0.1.
The program fails to compile with gcc giving an error U has not been declared
, compiles fine with clang and has a non-trivial assembly with icc.
Why is the behaviour different across these compilers?
I tried reading dependent_name but gave up since I couldn't follow it properly. From what little I understand, data member b
inside struct D
has a dependent type and U
should have been resolved when the template is instantiated.
Compiled the above code with the above compilers on godbolt.org here: https://godbolt.org/z/n_Wl44. I used C++17 with -O3 flag. Thanks in advance!!!
U
in b.U::foo();
should be looked up during instantiation in the context of B<T>
first, finding using U = A<T>;
, so that b.U::foo()
calls foo()
defined in A<T>
. [basic.lookup.classref]/4
The lookup should be delayed until instantiation and no lookup at definition should happen, because b
is dependent as its type depends on the template parameter T
. [temp.dep.expr]/5
Therefore this seems to be a bug in GCC. A very similar code example has been posted in this bug report, which demonstrates the same issue as far as I can tell. The bug is currently marked status "new".
As far as I can tell the other failing compilers shown in the godbolt.org conformance view posted by @TedLyngmo are derivatives of GCC, so it is not like independent compilers are disagreeing on this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With