在STL容器中存储属性?

发布于 2024-09-30 01:08:57 字数 788 浏览 10 评论 0原文

假设我有一个名为 generic_pair 的类,其形式为:

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

现在,问题是我希望能够在 STL 容器中存储一堆这些 generic_pairs 但是 并非全部 K、V>容器中的类型将相同。例如,一些元素可以是<<。 int, int >而其他人可能< int , 字符串 >等等。问题是我们怎样才能做到这一点?

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

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 或其他地方看到过类似的实现或相关工具/技术,那也会很有帮助。 (我试图避免宏)

Suppose I have a class called generic_pair of the form:

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

Now, the problem is I would like to be able to store a bunch of these generic_pairs in an STL container BUT not all < K, V > in the container will be of the same type. For example, some elements may be < int, int > whereas others may be < int , string > and so on. Question is how can we do this?

My first thought is to use "tags" to create a hierarchy of encapsulated types and declare the container with the generic type but actual elements with inherited types. For example,

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;

I bet there is a better, more correct way to do this? Any ideas, directions appreciated. If you have seen similar implementations or relevant tools/techniques in MPL or elsewhere that's helpful too. (I am trying to avoid macros)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

零時差 2024-10-07 01:08:57

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

You can use Boost.Variant if the set of types is determined in advance. If not, then Boost.Any might do the trick.

九八野马 2024-10-07 01:08:57

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

#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;
}

}

From your question and subsequent comments that clarify matters, the following would do what you're asking for:

#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;
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文