2016-06-23 5 views
0

以下の例では、かなり典型的なCRTPの例を示しています.2つの異なる派生クラスには、どちらもメソッドbarがあります。基底クラスは、単に転送し、いくつかにそれが型を持っている必要がありますので、私は、基本クラスの配列/ベクトル/などを持つことができるようにそれはいないようですbar方法異なるCRTP派生クラスメソッドを反復する

#include <iostream> 

template<typename Derived> 
class Base { 
public: 
    void foo() { 
     static_cast<Derived*>(this)->bar(); 
    } 
}; 

class DerivedA : public Base<DerivedA> { 
public: 
    void bar() { 
     ::std::cout << "A\n"; 
    } 
}; 

class DerivedB : public Base<DerivedB> { 
public: 
    void bar() { 
     ::std::cout << "B\n"; 
    } 
}; 

int main() { 
    DerivedA a; 
    DerivedB b; 
    a.foo(); 
    b.foo(); 
} 

を導出する方法fooを持っていますTが異なる

あるBase<T>の線に沿って、それらすべてが同じ方法(この場合はbar)を持っていると仮定すると別の派生クラスを反復処理することができることについてvirtualせずに大会のいくつかの種類がありますか?

答えて

2

Boost.Variantを使用できます。例:これは、あなたが(「労働組合を区別」を使って)ベクターまたは他のSTLコンテナ内の異種型を格納することができます、あなたは関係なく、自分が持っていないのそれらのすべてに特定の機能を呼び出すことができます

typedef boost::variant<DerivedA, DerivedB> Derived; 

struct BarCaller : public boost::static_visitor<void> { 
    template <class T> 
    void operator()(T& obj) { 
     obj.bar(); 
    } 
}; 

int main() { 
    std::vector<Derived> vec{DerivedA(), DerivedB(), DerivedA()}; 

    BarCaller bar; 
    for (Derived& obj : vec) { 
     obj.apply_visitor(bar); 
    } 
} 

共通の祖先または任意の仮想メソッド。

+0

完全な例を投稿しますか? – asimes

+0

の前に 'boost :: variant'を使用していません。' Base'はなく、 'DerivedA'と' DerivedB'だけが残っていると思いますか? – asimes

+0

@asimes:OK、あなたのクラス定義と組み合わせると、私の答えは完全に実行可能なプログラムになるように少し修正されました。あなたが 'Base'を持っているかどうかにかかわらず、私のコードはどちらの方法でも動作しません。 –

3

それはTが異なるBase<T>の線に沿って型がなければならないので、私は、基本クラスのアレイ/ベクトル/等を有することができるようにそれは思えません。それはあなたのために働く場合

あなたはすべてのTためBase<T>の基本クラスを持つことができ、そして、あなたは、基本クラスへのポインタのリスト/ベクトル/配列を持つことができます。

struct BaseOne 
{ 
    virtual void foo() = 0; 
    virtual ~BaseOne() {} 
}; 

template<typename Derived> 
class Base : struct BaseOne { 
public: 
    void foo() { 
     static_cast<Derived*>(this)->bar(); 
    } 
}; 

、その後、

int main() { 
    std::vector<BaseOne*> v {new DerivedA, new DerivedB }; 
    for (auto item : v) 
     item->bar(); 

    for (auto item : v) 
     delete item; 
} 

はすべて同じ方法(この場合はbar)を持っていると仮定すると別の派生クラスを反復処理することができることについてvirtualせずに大会のいくつかの種類がありますか?

いいえ、ありません。

関連する問題