c++ - 为什么 GCC 需要在模板中额外声明而 VS 不需要?

标签 c++ templates gcc

template<typename T>
class Base
{
protected:
    Base() {}
    T& get() { return t; }
    T t;
};

template<typename T>
class Derived : public Base<T>
{
public:
    Base<T>::get;                    // Line A
    Base<T>::t;                      // Line B
    void foo() { t = 4; get(); }
};

int main() { return 0; }

如果我注释掉 A 行和 B 行,这段代码在 Visual Studio 2008 下编译得很好。但是当我在 GCC 4.1 下编译并注释行 A 和 B 时,我得到了这些错误:

In member function ‘void Derived::foo()’:
error: ‘t’ was not declared in this scope
error: there are no arguments to ‘get’ that depend on a template parameter, so a declaration of ‘get’ must be available

为什么一个编译器需要 A 行和 B 行,而另一个不需要?有没有办法简化这个?换句话说,如果派生类使用来自基类的 20 个东西,我必须为从 Base 派生的每个类放置 20 行声明!有没有不需要这么多声明的方法?

最佳答案

GCC 在这种情况下是正确的,Visual Studio 错误地接受了格式错误的程序。看看 Name lookup 上的部分在 GCC 手册中。释义:

[T]he call to [get()] is not dependent on template arguments (there are no arguments that depend on the type T, and it is also not otherwise specified that the call should be in a [template-]dependent context). Thus a global declaration of such a function must be available, since the one in the base class is not visible until instantiation time.

您可以通过以下三种方式之一解决此问题:

  • 您已经在使用的声明。
  • Base<T>::get()
  • this->get()

(还有第四种方式,如果你想屈服于黑暗面:

Using the -fpermissive flag will also let the compiler accept the code, by marking all function calls for which no declaration is visible at the time of definition of the template for later lookup at instantiation time, as if it were a dependent call. We do not recommend using -fpermissive to work around invalid code, and it will also only catch cases where functions in base classes are called, not where variables in base classes are used (as in the example above).

但我不建议这样做,因为手册中提到的原因,以及您的代码仍然是无效的 C++ 的原因。)

关于c++ - 为什么 GCC 需要在模板中额外声明而 VS 不需要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2812470/

相关文章:

gcc - 无法使用 CMake 指定编译器

c++ - SSE 的整数/浮点值

c++ - Qt5 静态构建产生无法加载平台插件 "windows"

c++ - 为什么C++函数模板代码编译不通过?

c++ - 跨动态链接库的模板静态类

C++ 无效数组<T, N> 下标

c++ - 提取cpp中的所有包含文件

c++ - 对象数组的条目未更新

c - 交换C中多维数组的子数组

c - GCC 有包含但没有库