在C ++中,函数模板特应该作用酷似一个正常功能。这是否意味着我可以做一个虚拟的?

例如:

struct A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

struct B : A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

int main(int argc, char* argv[])
{
    B b;
    A& a = b;
    a.f<int>();
}

Visual Studio 2005中给了我以下错误:

  

致命错误C1001:已编译器中发生了内部错误

有帮助吗?

解决方案

尼斯编译错误。对于这种类型的检查,我总是去之前的标准和检查退回到科莫编译器。

  

科莫C / C ++ 4.3.10.1(2008年10月6日   11时28分09秒)的ONLINE_EVALUATION_BETA2   版权所有1988-2008科莫计算。   版权所有。模式:严格   错误C ++ C ++ 0x_extensions

     

“ComeauTest.c”,第3行:错误:   “虚拟”是不允许的功能   模板             宣言         模板虚拟无效F();                            ^

     

“ComeauTest.c”,第10行:错误:   “虚拟”是不允许的功能   模板             宣言         模板虚拟无效F();      ^

现在,因为它已经发布的其他用户,但事实是,标准没有允许你定义虚拟模板的方法。其基本原理是所有虚拟方法,一个条目必须在虚函数表保留。问题是,模板方法才会被定义时,他们已经被实例化(使用)。这意味着虚表最终会具有每个编译单元不同数量的元件,根据与不同类型的发生多少不同的呼叫到 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"
}

如果你想要这个概括为任何类型的,那么你的运气了。考虑另一种类型的委派,而不是多态性(聚合+代表团可能是一个解决方案)。于手头的问题的详细信息将有助于确定的溶液中。

其他提示

根据 http://www.kuzbass.ru:8086/docs /isocpp/template.html ISO / IEC 14882:1998:

  

-3-甲成员函数模板不得是虚的。

示例:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};

正如其他人指出,这是不合法的代码,因为成员函数模板不能声明virtual

然而,即使的Visual Studio 2012扼流圈此: “C 点击此处查看全尺寸

事件日志指示编译坠毁0xC0000005,或STATUS_ACCESS_VIOLATION。这很有趣,一定的(非法)代码构造如何使编译器段错误...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top