0

考虑以下代码:

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++ 不接受此代码时,对我有什么好处?

谢谢!弥敦道

4

2 回答 2

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)。

于 2012-05-29T11:49:49.407 回答
1

GCC详细诊断wiki 页面对此进行了介绍。

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

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

于 2012-05-29T13:06:29.237 回答