2012-03-05 16 views
0

テンプレート演算子を使用して、さまざまなユーザデータ型からさまざまな数のメンバ変数を宣言する方法はありますか?メンバ変数の汎用宣言

は、このコードを考えてみます。

class a { 
       int member; 
      void ProcessMemberVariable(); 
      }; 
    class b { 
       char member; 
      void ProcessMemberVariable(); 
      }; 
... // arbitrary number of such classes 



    class test { 

    template <typename T> 
    void declare (T a) { 
    // each time this member function is called a new member variable of the 
    // user data type T shall be declared in the instance of the class test?? 
    } 
    }; 

int() 
{ 
test Test; 
Test.template declare<a>(a A); 
Test.template declare<b>(b B); 
... 
} 

は、ユーザー定義のデータ型のいずれかの種類を設定するためのりんごであるインターフェイスを実装したい想像してみてください。私は...クラス「テスト」のインスタンスを宣言し、そのメンバ関数を呼び出す場合にのみ、ユーザー定義のデータ型の識別子を知っているので、私はそれぞれの提案に感謝

...

+1

あなたは 'declare'と、このような効果を使用したサンプルコードを示してもらえ – kennytm

+0

どのように使用してはどうですか? ['std :: vector'](http://en.cppreference.com/w/cpp/container/vector)または[' std :: list'](http://en.cppreference.com/w/cpp/container/list)を使って "変数"を保存するのですか? –

+1

これが可能ならば、名前が不明なメンバ変数にアクセスするコードをどのように書くことができますか?インスタンスとインスタンスは個別にアクセス可能になります – hmjd

答えて

2

何あなたのような音を記述しています動的にメンバーをオブジェクトに追加することができますが、これはC++では不可能です。特定の状況で同様の効果を得るにはさまざまな方法がありますが、これが役に立つと思った状況を説明する必要があります。

+0

私はもっと具体的なユースケースを意味しました。実行時にメンバーを追加したい場合。 –

+0

Andrei Alexandrescuは、現代C++デザインのテンプレートメタプログラミングを使用してコンパイル時にメンバーを追加する興味深いアプローチを探求します - 第3.13章タイプリストを使用したクラス生成。 – mark

2

実行時に動的にメンバー変数を追加する方法はありません。

しかし、実行時に追加したいタイプのリストが分かっていれば、boost :: variantを使ってこの動作を達成することができます。以下は、(

#include <iostream> 
#include <string> 
#include <map> 
#include <boost/variant.hpp> 

using namespace std; 

class Test 
{ 
    public: 
     typedef boost::variant< long, double, string > VariantType; 

     template< typename T > 
     void Declare(std::string name, T val) 
     { 
      VariantType newVal = val; 
      varMap.insert(std::make_pair(std::move(name), std::move(val))); 
     } 

     VariantType Get(const std::string& name) 
     { 
      return varMap[ name ]; 
     } 

     template< typename T > 
     T GetValue(const std::string& name) 
     { 
      return boost::get<T>(varMap[name]); 
     } 

    private: 
     std::map< string, VariantType > varMap; 
}; 


int main() 
{ 
    Test t{}; 

    t.Declare("Var1", 10l); 
    t.Declare("pi", 3.14159); 
    t.Declare("AString", "SomeName"); 

    cout << "t.get(Var1) " << t.GetValue<long>("Var1") << "\n"; 
    cout << "t.get(pi) " << t.GetValue<double>("pi") << "\n"; 
    cout << "t.get(AString) " << t.GetValue<string>("AString") << "\n"; 

    return 0; 
} 

を参照してください簡単な例です:ブーストを使用する方法の詳細については、http://www.boost.org/doc/libs/1_49_0/doc/html/variant.html ::バリアント