使用两种或多种数据类型的对象作为 C++ 映射、OOP 的键 [英] using objects of two or more data types as key for c++ map, OOP

查看:35
本文介绍了使用两种或多种数据类型的对象作为 C++ 映射、OOP 的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 mapclass.之前,有两种 maps,一种带有 char 键,另一种带有 string 键.我创建了一个包含 enumunionclass 和两个构造函数,一个来自 char,一个来自 字符串,重载比较运算符并使用该 class 作为键.

I have a class that contains a map. Earlier, there were two maps, one with char key and one with string key. I created a class that contains enum and union and two constructors, one from char and one from string, overloaded comparison operator and used that class as key.

但我一直在想.这可以通过巧妙地使用继承来解决吗?

But I keep wondering. could this have been solved with clever use of inheritance instead?

我的课程大致如下:

class A
{
    enum B
    {
        Ax, Ay
    } b;
    union C
    {
        X x;
        Y y;
    } c;
 public:
    A(X x) : b(Ax), c(x) {}
    A(Y y) : b(Ay), c(y) {}
    bool operator<(A& rhs)
    {
        if(this->b == rhs.b)
        {
            if(this->b == Ax) return this->c.x < b.c.x;
            if(this->b == Ay) reutrn this->c.y < b.c.y;
        }
        // if the "type" is different, I assume values are different
        // and all I need is any strong ordering, actual order doesn't matter
        return this->b < rhs.b;
    }
};

稍后我可以使用它fe.像这样:

Later on I can use it fe. like that:

class Q
{
    // ...
public:
    Q(vector<A> v)
    {
        // don't worry about this code, I haven't figured out how c++11 for each
        // works exactly yet, but it's not important, I can do that myself
        for each (auto a in v)
        {
            // ...
        }
    }
};

现在使用大括号,我可以用各种 A 初始化 Q,并且我可以从 char 创建不同的 A> 或 string.

Now using curly brackets I can initialize Q with various A, and I can create distinct A from char or string.

我的班级,A通过包含用于比较一种类型的键所需的实际数据的联合,以及用于比较不同类型的键的枚举来实现这一点.具有虚拟基类和两个子类的基本继承树将导致每个实例包含相同数量的信息——不同的内部变量将扮演联合的角色,而不同的实际类将扮演枚举的角色.但我就是想不出一种方法来正确地做到这一点,而不违反任何重要的原则.

My class, Aaccomplished this by containing union for the actual data required to compare keys of one type, and enum used to compare keys of different types. Basic inheritance tree with virtual base class and two subclasses would result in every instance containing the same amount of information - different internal variables would take role of the union, and different actual classes would take the role of the enum. But I just can't come up with a way to do it properly without breaking any important principles.

推荐答案

为什么不使用 boost::variantstd::variant 一旦后者在您的编译器中可用?

Why not use boost::variant or std::variant once the latter becomes available in your compiler?

感觉就像是最自然的问题解决方案,并且使代码非常易读:

It feels like the most natural solution to the problem and makes the code very readable:

#include <boost/variant.hpp>

#include <string>
#include <map>
#include <iostream>

int main()
{
    using Key = boost::variant<char, std::string>;
    using Value = int; // whatever
    std::map<Key, Value> map;
    map['A'] = 1;
    map["B"] = 2;
    map["A"] = 3;

    for (auto&& key_value : map)
    {
        std::cout << key_value.first << " => " << key_value.second << '\n';
    }
}

输出:

A => 1
A => 3
B => 2

这篇关于使用两种或多种数据类型的对象作为 C++ 映射、OOP 的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆