-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
For the following code
template <typename = int> struct C
{
C &foo(const C &c) { return operator =(c); }
};
int main()
{
C<> c;
c.foo(c);
}
Clang will generate a diagnostic
error: explicit qualification required to use member 'operator=' from dependent base class
3 | C &foo(const C &c) { return operator =(c); }
|
The code appears to be perfectly valid, yet it is rejected by Clang. The above diagnostic mentions "base class", although obviously there's no inheritance of any kind in this code.
Prepending the call to copy-assigment with this->
C &foo(const C &c) { return this->operator =(c); }
solves the problem (which incidentally is how one solves the "lookup in a dependent base class" issues).
Switching from functional notation to operator-in-expression notation makes the error to go away
C &foo(const C &c) { return *this = c; }
Trying to qualify the call
C &foo(const C &c) { return C::operator =(c); }
results in
error: no member named 'operator=' in 'C<type-parameter-0-0>'
3 | C &foo(const C &c) { return C::operator =(c); }
|
Also, adding an explicit declaration of the copy-assigment operator
C &operator =(const C &) = default;
solves the issue as well.
With non-template classes the issue does not manifest itself.
The diagnostic implies that when functional notation is used to refer to the implicitly declared copy-assignment operator in a template class (from within a member definition), name lookup fails for some unknown reason, and the compiler immediately jumps to conclusion that it is a "lookup in a dependent base class" issue. It obviously is not.
Anyway, is this a known issue? Or am I missing some peculiarity of name lookup in template classes?