在模板基类中的虚函数中使用前向声明的类,其中构造函数只需要前向声明?

das*_*ndy 3 c++ gcc templates visual-c++

我试图找出失败的原因.我正在使用的代码基本上压缩到下面的代码.我有一个简单的A类,我专门用一个模板.模板不需要这种类型来编译它的构造函数,并且我实际调用的构造函数(派生类型)没有公开,因此编译器此时无法为构造函数生成代码.

GCC和Clang没有.然而,MSVC(2008 + 2010)确实尝试编译虚拟成员,因此不进行编译.

这是错误的GCC和Clang,还是来自MSVC?或者我是否会进入UB领土?

class A;

template <typename X>
class S {
public:
    S() {}

    virtual int useX() { return X::value; }
};

class T : public S<A> {
public:
    T();
};

int main()
{
    new T();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*sky 8

当MSVC实例化一个类时,它还会填充其vtable,并为此目的实例化其所有虚函数,即使是那些从未调用过的函数.

在您的情况下,如果useX没有编译器看到A的完整定义,则无法实例化该函数.

如果您将useX声明为非虚拟,则MSVC可以正常工作.

看来这种行为依赖于编译器; 例如,AIX在实例化(未使用)函数时比MSVC更具攻击性.