仮想機能のテンプレート化に関する質問

c++ templates
仮想機能のテンプレート化に関する質問

仮想関数をテンプレート化できないことは知っていますし、その背後にある概念も理解しています。 しかし、私はまだ私が得ているいくつかのエラーを乗り越える方法が必要です。 私は自分のものを機能させることができますが、私には正しく見えません。

`System`というクラスがあります:

#include "Vector.h"
class System
{
    virtual void VectorToLocal(Vector& global_dir,const Vector* global_pos =  0)      const  = 0;
};

class UnresolvedSystem : public System
{
    virtual void VectorToLocal(Vector& global_dir,const Vector* global_pos = 0) const
    {
      //do something
    }
};

`Vector.h`内:

tenplate
class Vector
{
  //some functions
};

今、 system.h`の VectorToLocal`をテンプレート化して、ちょうど `Vector`を取得したいのですが、それは仮想関数なので、できません。 回避策が必要です。 「VectorToLocal」で「Vector」や「Vector」などを引数として取ることができることは知っていますが、それはしたくありません。

  1  0


ベストアンサー

メンバー関数テンプレートを仮想にすることはできません。 それについて2つの方法はありません。

しかし、仮想メンバー関数は、たまたまテンプレートを使用する完全に定義された型を取ることができます。

class System
{
public:
    virtual void DoIt(vector* v);
};


int main()
{
    vector v;
    System s;
    s.DoIt(&v);
    return 0;
}

ところで、なぜ独自のベクタークラスを実装するのですか?

2


CRTPなどの仮想機能を削除する一般的な方法も役立ちます。

1


あなたのベクトルで何をしたいのか分かりませんが、実際の動作を実装する仮想関数をテンプレート関数の呼び出しにすることが可能です。 その場合、スーパークラスでテンプレートバージョンを実装し、そこで何でもやりたいことを行う非テンプレートの純粋仮想を呼び出すようにします。 これは通常、type-parameterに制限を加えた場合にのみ機能します。

#include "Vector.h"
class System
{
    virtual void print( const std::string & ) const = 0;
    template
    void VectorToLocal(Vector& global_dir,const Vector* global_pos =  0) const {
        print( T.GetName() );
    }
};

class UnresolvedSystem : public System
{
    virtual void print( const std::string & Name ) const {
        std::cout << name << std::endl;
    }
};

この場合、「T」にはメンバー関数「GetName」があると仮定しました。

0


C ++テンプレート関数を定義すると、テンプレート引数タイプの組み合わせごとに新しい関数実装が作成されます。 したがって、ソース内の単一の関数は、マシンコード内の1つまたはhunderds関数である可能性があります。 それは彼らを速くするのに役立ちます。

現在、コンパイラーは、どのように呼び出されるかによって生成する関数のバージョンを決定します。 `int`が決して型パラメーターではない場合、コンパイラーは実装を生成するためにサポートされていません。 呼び出しを仮想化すると、その使用方法を見つけるのが難しくなり、テンプレート関数を使用する関数をコンパイルするときに、関数の定義がヘッダーファイルにない可能性があります。 関数のソースコードがないと、コンパイラはコンパイルされた関数を作成できません。

C ++が仮想テンプレート機能を許可するときに直面する他の非現実性がいくつかあります。 仮想機能の一般的な実装方法と同様。

そして、それがおそらくC ++がそれを許可しない理由です。 あなたはそれが必要だと思うかもしれませんが、おそらく別の方法があります。このコードスニペットの背後にある要件についてもう少し詳しく教えてくれると、人々があなたを見つけるのに役立つと確信しています。

0


いくつかのオプションがあり、そのすべてがあなたがしようとしていることに依存しています。

T`が何らかの形で System`に固有の場合(たとえば、 System`に T`型のメンバー変数がある場合)、クラス全体をテンプレート化できます:

template< typename T >
class System
{
    virtual void VectorToLocal(Vector& global_dir,const Vector* global_pos =  0)      const  = 0;
};

template< typename T >
class UnresolvedSystem : public System
{
    virtual void VectorToLocal(Vector& global_dir,const Vector* global_pos = 0) const
    {
      //do something
    }
};

「T」のコンテキストが「VectorToLocal」のみに対してローカルである場合、より良い設計上の決定は、クラス外の関数を因数分解することです。

template< typename T >
void VectorToLocal( System& s, Vector& global_dir, ... )
{
   // use s's public interface to make changes to the object
}

「VectorToLocal」の目的に関する詳細を教えてください。

0


単一の実装ポイントを提供したい場合は、呼び出しをテンプレートに転送できます

struct base {
   virtual void f( int );
   virtual void f( double );
};

struct derived : base {
   virtual void f( int x ) { f_tmpl(x); }
   virtual void f( double x ) { f_tmpl(x); }

   template
   void f_tmpl( T x ) { // ... }
};

タイプリストを使用すると、実際に仮想関数を生成できると思いますが、それはおそらくコードを複雑にするだけです。

0


タイトルとURLをコピーしました