我有以下代码:
在gcc-3.4、gcc-4.3、intel编译器下编译没有问题,在MSVC9下编译失败。
MSVC 告诉“使用未定义类型 c_traits<C>
,同时编译类模板成员函数 void foo<C>::go(void)
与 C=short。
编译器试图安装未使用类的未使用成员函数,因为 根本没有使用这个类。
我可以通过专门化整个类 foo 而不是专门化来解决这个问题 它的成员函数。但重点是,由于不同的原因,对整个类(class)进行特化对我来说有点问题。
大问题:什么是正确的?
- 我的代码是否错误,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;
}
最佳答案
两个编译器都在这里;您的案例的行为未指定。 ISO C++ 14.7.1[temp.inst]/9:
An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class or a static data member of a class template that does not require instantiation. It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated.
这样做的原因很简单:虚函数需要一个虚表条目,并且使用虚拟分派(dispatch),编译器可能很难确定给定的虚函数是否实际被调用。因此,ISO C++ 允许编译器为了生成更小的代码而进行此类高级分析,但并不要求它们这样做——因此,作为 C++ 程序员,您应该始终假设所有虚函数都将始终被实例化。
关于c++ - 使用无法安装的类的有效 STATIC 成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1662905/