在STL容器中存储属性?

时间:2010-11-02 23:31:49

标签: c++ templates boost-mpl

假设我有一个名为generic_pair的类:

template < typename K, typename V >
struct generic_pair{
  K key;
  V value;
};

现在,问题是我希望能够将一堆这些generic_pairs存储在STL容器中 BUT 并非所有&lt; K,V>在容器中将是相同类型。例如,一些元素可以是&lt; int,int&gt;而其他人可能&lt; int,string&gt;等等。问题是我们该怎么做?

我的第一个想法是使用“tags”来创建封装类型的层次结构,并使用泛型类型声明容器,但使用继承类型声明实际元素。例如,

struct base_type{
  typedef void type;
};

struct int_type: base_type{
  typedef int type;
}

struct string_type: base_type{
  typedef std::string type;
}

/// and so on establish a type hierarchy as necessary and then...

std::vector < generic_pair < base_type, base_type > > vec;

我敢打赌有更好,更正确的方法吗?任何想法,方向赞赏。如果您在MPL或其他地方看到类似的实现或相关工具/技术也很有帮助。 (我试图避免使用宏)

2 个答案:

答案 0 :(得分:3)

如果预先确定了类型集,则可以使用Boost.Variant。如果没有,那么Boost.Any可能会成功。

答案 1 :(得分:3)

根据您的问题以及随后澄清问题的评论,以下内容可以满足您的要求:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

// All class-template instantiations derive from this
struct AbstractPair
{
    virtual std::string serialize() const = 0;
};

template<typename K, typename V>
struct Pair : public AbstractPair
{
public:
    Pair(K key, V value) : key(key), value(value) {}

    std::string serialize() const
    {
        std::stringstream ss;
        ss << "Key: " << key << ", Value: " << value;
        return ss.str();
    }
    K key;
    V value;
};


int main()
{
    // Vector of pointers-to-abstract-base
    std::vector<AbstractPair *> v;

    // Create derived objects (instantiate class template)
    AbstractPair *p1 = new Pair<int,int>(5,10);
    AbstractPair *p2 = new Pair<float,std::string>(3.2f, "Hello");

    // Valid, and type-safe
    v.push_back(p1);
    v.push_back(p2);

    // Demonstrate polymorphism
    for(std::vector<AbstractPair *>::iterator it = v.begin(); it != v.end(); ++it)
    {
        std::cout << (*it)->serialize() << std::endl;
    }

    // Boilerplate cleanup
    delete p1;
    delete p2;
    return 0;
}

}