https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110806

            Bug ID: 110806
           Summary: Suggest this-> for dependent base classes in more
                    contexts
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

Consider this [broken] program:

template <typename T>
struct Outer {
    struct Inner {
        template <typename F>
        void wait(F f);
    };

    struct InnerD : Inner {
        template <typename F>
        void advance(F f) {
            wait(f);
        }
    };

    #ifdef OUTER
    template <typename F>
    void wait(F f);
    #endif
};

void f(Outer<int>::InnerD i) {
    i.advance(42);
}

gcc's compile error is:

<source>: In instantiation of 'void Outer<T>::InnerD::advance(F) [with F = int;
T = int]':
<source>:22:14:   required from here
<source>:11:17: error: 'wait' was not declared in this scope, and no
declarations were found by argument-dependent lookup at the point of
instantiation [-fpermissive]
   11 |             wait(f);
      |             ~~~~^~~
<source>:11:17: note: declarations in dependent base 'Outer<int>::Inner' are
not found by unqualified lookup
<source>:11:17: note: use 'this->wait' instead

This is pretty good - indicates what the problem is and suggests the correct
fix.

However, if you compile with -DOUTER, such that lookup for wait(f) ends up
finding Outer<T>::f, you get this error:

<source>: In instantiation of 'void Outer<T>::InnerD::advance(F) [with F = int;
T = int]':
<source>:22:14:   required from here
<source>:11:17: error: cannot call member function 'void Outer<T>::wait(F)
[with F = int; T = int]' without object
   11 |             wait(f);
      |             ~~~~^~~

If we had the exact same note in this context too, that'd be very helpful -
since if what you meant to call was Inner::wait, the fact that you cannot call
Outer::wait isn't really useful. Plus when the names of these types are a
little longer, the error message can be pretty confusing if you gloss over the
fact that the error is reporting that you tried to call void Outer<T>::wait and
not void Outer<T>::Inner::wait!
  • [Bug c++/110806] New: Suggest t... barry.revzin at gmail dot com via Gcc-bugs

Reply via email to