不错的编译器错误。对于这种类型的检查,我总是在回到标准和检查之前回退到Comeau编译器。
用于 ONLINE_EVALUATION_BETA2 的 Comeau C/C++ 4.3.10.1(2008 年 10 月 6 日 11:28:09) 版权所有 1988-2008 Comeau Computing。版权所有。模式:严格错误 C++ C++0x_extensions
“ComeauTest.c”,第 3 行:错误:在函数模板声明模板中不允许使用“virtual” virtual void f(); ^
“ComeauTest.c”,第 10 行:错误:函数模板声明模板中不允许使用“virtual” virtual void f(); ^
现在,正如另一个用户发布的那样,事实是该标准不允许您定义虚拟模板化方法。基本原理是对于所有虚拟方法,必须在 vtable 中保留一个条目。问题是模板方法只有在它们被实例化(使用)时才会被定义。这意味着 vtable 最终将在每个编译单元中具有不同数量的元素,具体取决于对f()的不同类型的不同调用的次数。然后地狱就会升起...
如果您想要的是其参数之一上的模板化函数并且一个特定版本是虚拟的(请注意参数的一部分),您可以这样做:
class Base
{
public:
template <typename T> void f( T a ) {}
virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}
如果您希望将其概括为任何类型,那么您就不走运了。考虑另一种类型的委托而不是多态(聚合+委托可能是一种解决方案)。有关手头问题的更多信息将有助于确定解决方案。