g ++从带有模板参数的类派生

时间:2012-05-29 11:31:49

标签: c++ templates g++ compiler-options

考虑以下代码:

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

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

在评论“受影响的行”的行中,g ++(4.7)说:

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]

现在我想知道:

  • 如果模板参数T不存在,则不会发生此错误。有什么区别?
  • g ++显然能够解决这个问题(如果我添加-fpermissive它可以很好地编译)。我假设g ++试图为我作为“用户”(程序员)提供最好的体验。当g ++不接受这段代码时,有什么好处?

谢谢! 森

2 个答案:

答案 0 :(得分:2)

如果您不添加thisBase<T>,则编写的代码不符合标准 - GCC希望阻止您这样做。另请参阅GCC 4.7的更改日志条目:

  

G ++现在正确地实现了两阶段查找规则,使得模板中使用的非限定名称必须具有在模板定义点的范围内找到的适当声明,或者在实例化时通过参数依赖查找。因此,在实例化时依赖于第二次非限定查找以查找在模板之后或在依赖基础中声明的函数的代码将被拒绝。编译器将建议修复受影响代码的方法,并使用-fpermissive编译器标志将允许代码使用警告进行编译。

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();
}

(在此处找到:http://gcc.gnu.org/gcc-4.7/changes.html)。

答案 1 :(得分:1)

这在GCC Verbose Diagnostics维基页面中有所介绍。

  

当g ++不接受此代码时,对我有什么好处?

符合标准并与其他编译器一致,确保您的代码可移植且正确。