2017-12-15 3 views
1

正しいクラスのメソッドを選択して実行するT型のオブジェクトを受け入れるテンプレート関数を用意したいと思います。 このような何か、入力タイプに基づいて構造体の正しいメソッドを選択する

struct TypeX 
{}; 
struct TypeY 
{}; 

struct X 
{ 
    void Do(TypeX &r){} 
}; 
struct Y 
{ 
    void Do (TypeY & r){} 
}; 

template<typename T> 
void Do(T& r) 
{ 
    // if(T==TypeX) call X::Do(r)  
} 

そして、私の解決策は

template<class V, typename T> 
void Do(T& r) 
{ 
    V::Do(r);  
} 

または

template<class B, typename T> 
void Do(B*p, T& r) 
{ 
    p->Do(r);  
} 

のいずれかとなり、それは私のmain.cppで欠陥、例えば に見えますが、私はBポインタを作成する必要があります として B*p=new X; またはB*p=new Y と私は動的割り当てが嫌い、の入力をmainに導入していません。私は関数のいずれかのTypeXまたはTypeYの1つのパラメータを受け入れるだけで、XまたはYから対応するメソッドを呼び出すために入力を区別しなければなりません。

答えて

1

代わりに動的多型を使用することをお勧めします。これを実現するには、仮想関数の継承を使用します。まず、抽象クラスとして機能定義クラスBase

class Base { 
public: 
    virtual void Do() = 0; 
}; 

両方XYこのクラスBaseから派生します。あなたがしなければならないのは、選択することで

struct X x; 
struct Y y; 

Base *p = &x //or &y 

を:あなたは全く動的割り当てを必要としない

struct X: public Base { 
    // define your Do() function member for X 
    virtual void Do() override { 
     ... 
    } 
}; 

struct Y: public Base{ 
    // define your Do() function member for Y 
    virtual void Do() override { 
     ... 
    } 
}; 

XYの両方がそうでない場合は、インスタンス化することはできません、Do()メンバ関数を実装する必要があります適切なstruct(つまり、XまたはYのいずれか)を入力タイプに基づいてインスタンス化し、そのオブジェクトのアドレスをBaseへのポインタに割り当て、Do()

Base *p = // <-- address of struct X or struct Y object 
p->Do(); 

あなたがインスタンス化されたオブジェクトの種類に基づいて呼び出されるの適切なDo()メンバ関数:struct Xまたはstruct Yのいずれか。あなたは、タグではなく、派遣が、それは書くために多くのコードを必要としてみることもでき、その前に

template<typename T> 
void Do(T& r) 
{ 
    if constexpr (std::is_same_v<T, TypeX>) { 
     X::Do(r); 
    } else { 
     Y::Do(r); 
    } 
} 

Example

:あなたはif constexprを使用することができC++ 17ので

1

関連する問題