15

C ++では、関数テンプレートの特殊化は、通常の関数とまったく同じように機能することになっています。それは私が1つを仮想化できることを意味しますか?

例えば:

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:コンパイラで内部エラーが発生しました。

4

3 に答える 3

23

ニースのコンパイルエラー。このタイプのチェックでは、標準に戻ってチェックする前に、必ずComeauコンパイラにフォールバックします。

Comeau C/C++ 4.3.10.1 (2008 年 10 月 6 日 11:28:09) ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. 全著作権所有。MODE:厳密なエラー C++ C++0x_extensions

"ComeauTest.c"、3 行目: エラー: "virtual" は関数テンプレート宣言テンプレートでは許可されていません virtual void f(); ^

"ComeauTest.c"、10 行目: エラー: "virtual" は関数テンプレート宣言テンプレートでは許可されていません virtual void f(); ^

現在、別のユーザーによって投稿されているように、実際には、標準では仮想テンプレート メソッドを定義することはできません。その根拠は、すべての仮想メソッドについて、vtable でエントリを予約する必要があるということです。問題は、テンプレート メソッドがインスタンス化 (使用) された場合にのみ定義されることです。これは、異なるタイプのf()への異なる呼び出しがいくつ発生するかに応じて、vtable が各コンパイル単位に異なる数の要素を持つことになることを意味します。それから地獄が上がるだろう...

引数の 1 つにテンプレート化された関数が必要で、1 つの特定のバージョンが仮想である場合 (引数の一部に注意してください)、次のように実行できます。

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"
}

これを任意のタイプに一般化したい場合は、運が悪いです。ポリモーフィズムではなく、別の種類の委任を検討してください (集約 + 委任が解決策になる可能性があります)。当面の問題に関する詳細情報は、解決策を決定するのに役立ちます。

于 2009-04-16T18:13:37.110 に答える
4

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
};
于 2009-04-16T18:08:47.653 に答える
1

他の人が指摘したように、メンバー関数テンプレートを宣言できないため、これは正当なコードではありませんvirtual

しかし、Visual Studio 2012 でさえ、これで窒息し ます。Visual Studio 2012 での C++ 内部コンパイラ エラー フル サイズはここをクリックしてください。

イベント ログは、0xC0000005、またはでコンパイラがクラッシュしたことを示していSTATUS_ACCESS_VIOLATIONます。特定の(違法な)コード構造がコンパイラのセグメンテーション違反を引き起こす可能性があるのは面白いです...

于 2012-11-27T11:01:13.347 に答える