使用无法安装的有效STATIC成员函数

Art*_*yom 6 c++ specialization visual-c++

我有以下代码:

它在gcc-3.4,gcc-4.3,intel编译器下编译没有问题,但在MSVC9下失败.

MSVC告诉"使用未定义的类型c_traits<C>,同时void foo<C>::go(void)使用C = short 编译类模板成员函数.

编译器试图安装未使用的类的未使用的成员函数,因为这个类根本就没用过.

我可以通过专门化整个类foo而不是专门化其成员函数来解决这个问题.但是,由于各种原因,专门针对整个班级的问题对我来说有点问题.

最大的问题:什么是对的?

  • 我的代码是错误的,gcc和intel编译器只是忽略了这个问题,因为它们没有完全安装foo,或者
  • 代码是正确的,这是MSVC9(VC 2008)的错误,它试图安装未使用的成员函数?

代码:

class base_foo {
public:
    virtual void go() {};
    virtual ~base_foo() {}
};
template<typename C>
struct c_traits;

template<>
struct c_traits<int> {
    typedef unsigned int_type;
};

template<typename C>
class foo : public base_foo {
public:
    static base_foo *create()
    {
        return new foo<C>();
    }
    virtual void go() 
    {
        typedef typename c_traits<C>::int_type int_type;
        int_type i;
        i=1;
    }
};

template<>
base_foo *foo<short>::create()
{
    return new base_foo();
}

int main()
{
    base_foo *a;
    a=foo<short>::create(); delete a;
    a=foo<int>::create(); delete a;
}
Run Code Online (Sandbox Code Playgroud)

Pav*_*aev 3

两个编译器都在这里;您的案例的行为未指定。ISO C++ 14.7.1[临时实例]/9:

实现不得隐式实例化不需要实例化的函数模板、成员模板、非虚成员函数、成员类或类模板的静态数据成员。如果虚拟成员函数不会被实例化,则未指定实现是否隐式实例化类模板的虚拟成员函数。

其原因相当简单:虚拟函数需要一个 vtable 条目,并且通过虚拟分派,编译器可能很难确定给定的虚拟函数是否被实际调用。因此,ISO C++ 允许编译器进行此类高级分析以生成更小的代码,但并不要求编译器这样做 - 因此,作为 C++ 程序员,您应该始终假设所有虚拟函数都将始终被实例化。