The following C++ code gives an error with GCC (e.g. 13.1, see godbolt.org) where the compiler seems to confuse the set member function template with std::set:
#include <set>
using namespace std;
template <typename T> struct C {
template <int S> void set(T const &) { }
};
template <typename T> struct D : C<T> {
void f(T const & v) { this->template set<0>(v); }
};
It has obviously something to do with the using namespace std; line but I don't understand how the compiler can try to lookup set in the global or std namespace when it is explicitly qualified by this->. Can anyone enlighten me?
There is a GCC bug report about this here.
According to the comments there is a relevant C++ standard defect report regarding the behavior, but I couldn't find it.
For a bit of context:
When you have a class member access expression like X->Y (assuming no operator-> overload), lookup for Y is done first in the context of the class type of X.
But if that doesn't succeed, then lookup for Y is also done in the scope of the expression. This would e.g. find std::set if Y is set and you have a using namespace std; in scope (template doesn't affect the lookup). Because your base class C<T> is dependent its member set won't be found in the first lookup phase from the template definition context.
This lookup rule allows you to write e.g. this->set<int>::size() if the current class is derived from set<int>.
The question now is how this is supposed to interact with the current class having a dependent base that could cause lookup for set to find its member instead in the instantiation context.
I haven't looked up what the current and previous standards say about this exactly.
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