Question

consider the following code:

template<class T>
class Base {
  public:
    void doSomething(){}
};

template<class T>
class Derived : public Base<T> {
  public:
    void doMore() {
      doSomething(); //Affected line
    }
};

In the line commented with "affected line" g++ (4.7) says:

test.cc:11:16: error: there are no arguments to ‘doSomething’ that depend on a template parameter, so a declaration of ‘doSomething’ must be available [-fpermissive]

Now I am wondering:

  • If the template parameter T would not be there, this error would not occure. What is the difference?
  • g++ obviously is able to resolve this problem (if I add -fpermissive it compiles fine). I am assuming that g++ tries to make the best experience for me as the "user" (programmer). What are the advantages for me when g++ does not accept this code?

Thanks! Nathan

Was it helpful?

Solution

This is covered in the GCC Verbose Diagnostics wiki page.

What are the advantages for me when g++ does not accept this code?

It conforms to the standard and agrees with other compilers, ensuring your code is portable and correct.

OTHER TIPS

If you do not add this or Base<T> you write code that is not standard conforming - GCC wants to prevent you from doing this. See also the Changelog entry for GCC 4.7:

G++ now correctly implements the two-phase lookup rules such that an unqualified name used in a template must have an appropriate declaration found either in scope at the point of definition of the template or by argument-dependent lookup at the point of instantiation. As a result, code that relies on a second unqualified lookup at the point of instantiation to find functions declared after the template or in dependent bases will be rejected. The compiler will suggest ways to fix affected code, and using the -fpermissive compiler flag will allow the code to compile with a warning.

template <class T>
void f() { g(T()); } // error, g(int) not found by argument-dependent lookup
void g(int) { } // fix by moving this declaration before the declaration of f

template <class T>
struct A: T {
  // error, B::g(B) not found by argument-dependent lookup
  void f() { g(T()); } // fix by using this->g or A::g
};

struct B { void g(B); };

int main()
{
  f<int>();
  A<B>().f();
}

(found here: http://gcc.gnu.org/gcc-4.7/changes.html).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top