2016-09-30 20 views
1

私はタプルのようなデータ構造を試してきました。オブジェクトの各タイプは1つだけで、各オブジェクトはCスタイルのPODSでなければなりません。それはそれが保持するオブジェクトにアクセスする奇妙な方法を使用します。そこから派生するクラスへの参照を返します。同様に:親クラスへの参照を戻すC++

template<class... Ts> 
class Container : private Ts... 
{ 
public: 
    template<class T> 
    T& get_component() 
    { //returns reference to base class specified by T 
     return static_cast<T&>(* const_cast<Container<Ts...> *>(this)); 
    } 
}; 

そして、このように使用されることを意図:

struct A { int x, y; }; 
struct B { float x, y; }; 

int main() 
{ 
    using namespace std; 

    Container<A, B> foo; 
    A& a_ref = foo.get_component<A>(); 

    a_ref.x = 5; 
    a_ref.y = 10; 

    const B& b_ref = foo.get_component<B>(); 

    cout << b_ref.x << endl; 
    cout << b_ref.y << endl; 
} 

私が使用する方法は、T &にそれをstatic_castsよりも、それを逆参照、これをconst_castをしなければなりません。私が使っているテクニックに落とし穴がありますか?私が試したテストでは、このデザインは期待どおりに動作するようです。

編集: const_castは冗長です。私はこのポインタへの参照を割り当てるという誤解を持っていました。私はちょうどstatic_casting T &これを逆参照する必要があります。

+1

なぜ最初に 'const_cast'を使用していますか?あなたは同じタイプにキャストしているだけです。 – 0x499602D2

+0

'const'を追加したい場合は' static_cast'を使うことができます – krzaq

+1

@krzaqあるいは戻り値の型を 'const T&'に変更して関数 'const'を作るだけです – user4407569

答えて

1

は、私の知る限り、これを言うことができるようにだけに簡略化することができます:あなたは、彼らが民間の基底クラスである理由を、私は疑問午前のコンポーネントを取得するために許可されている場合は

template<class... Ts> 
class Container : private Ts... 
{ 
public: 
    template<class T> 
    T& get_component() 
    { 
     return *this; 
    } 

    template<class T> 
    const T& get_component() const 
    { 
     return *this; 
    } 
}; 

コードに一つの可能​​な問題は、例えば、同じベースタイプの複数の出現箇所である:

struct A {}; 
struct B : A {}; 

Container<A,B> container; 
auto& a_ref = container.get_component<A>(); 

誤差を与えます。プライベート基地の代わりにプライベートデータのメンバーを使用することで、get_componentが即時の拠点でのみ動作するようにすることで、このようなことを避けることができます。

+0

理由の1つは、AとBの両方にメンバーxがあるため、foo.xがあいまいであると言うあいまいさを解決することです。 – Brian

+0

@Brian:公的な拠点を使っていれば、単に 'A&a_ref = foo; 'を使うだけで、' get_component'は不要です。 – user4407569

関連する問題