成员变量的通用声明

时间:2012-03-05 13:56:36

标签: c++ templates c++11

有没有办法通常使用模板运算符从不同的用户数据类型声明各种成员变量?

考虑这段代码:

    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);
...
}

想象一下你想要实现一个苹果接口来设置任何类型的用户定义数据类型。因为只有当我声明类“test”的实例并调用其成员函数时才知道用户定义数据类型的标识符...

我很欣赏每一个建议......

2 个答案:

答案 0 :(得分:2)

您所描述的内容听起来像是动态地向对象添加成员,这在C ++中是不可能的。在某些情况下有各种方法可以获得类似的效果,但您需要描述一种您认为有用的情况。

答案 1 :(得分: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;
}

有关如何使用boost :: variant的详细信息,请参阅:http://www.boost.org/doc/libs/1_49_0/doc/html/variant.html