是否可以定义(以简单的方式,可能重新使用std容器)"关联std::tuple
",或换言之," variadiac {{ 1}}"
像这样的东西(这个界面只是为了解释,欢迎其他可能的接口):
std::map
其他理想的约束:
AssociativeTuple<std::string> at; // std:string is the key type
at.insert<float>("my_float", 3.14); // 1.
at.insert<int>("my_int", 42);
at.insert<bool>("my_bool", true);
at.insert<int>("xyz", 0);
at.insert<std::string>("my_string", "hello world!");
assert(get(at, "my_float") == 3.14); // 2.
assert(get(at, "my_int") == 42);
assert(at["my_string"] == "hello world!"); // 3.
assert(std::is_same<at.type_of("my_float")::type, float>) // 4.
for (auto it : at) { std::cout << it.first << " = " << it.second; } // 5.
将是"my_float"
。换句话说,设置可能的键是固定的,并且对应于键的值的类型在编译时是已知的。在编译时不知道的是&#34;如果&#34;一个键将插入容器内。当然,在编译时不知道映射值的值。float
应该快速我真正的问题是get
/ float
/ int
类型的价值(而我正在做的是存储在bool
中的所有内容并转换为{必要时std::map<std::string, float>
),但需要一般解决方案。在我的实际情况中,密钥始终是int
。
答案 0 :(得分:3)
您可能意味着具有多态值的地图。对于多态值,您可以使用boost::any
或更好的boost::variant<>
。 E.g:
typedef boost::variant<int, double, std::string> MyVariant;
typedef std::map<std::string, MyVariant> MyPolymorphicMap;
答案 1 :(得分:1)
这个怎么样? (注意:值不是元组;每个键有一个值。)
template<class K> using AnyMap = std::map<K, boost::any>;
AnyMap map;
map["test1"] = 124;
map["test2"] = std::string{ "some text" };
auto value = boost::any_cast<int>(map["test1"]);
答案 2 :(得分:0)
是的,这可以使用一个变体(那里有很多实现)或一般的某种包装器,基于一个联合(在你的情况下是首选方式)或派生自一个公共基类。
对于像get(at, "my_int") == 42
这样的东西,你必须重载等于运算符bool operator==(Variant&, int)
,但这也不应该是一个问题。
你不能做像std::is_same<at.type_of("my_float")::type, float>
之类的东西,因为is_same是一个编译时表达式,但是类型(你正在寻找)只在运行时才知道。但是,您仍然可以定义执行该检查的运行时函数。
但是:如果 - 在您的特定情况下 - 您只需要int
和float
并且您没有很难记住内存(使用字符串作为键似乎表明这一点),那么我只是使用double
因为它可以代表您可能想要存储的任何数字。
另一种可能性是使用两个独立的数据结构(一个用于int,一个用于float)。如果有必要,您还可以围绕这些构建一个rwarpper,以使它们看起来像一个。如果您的programlogic总是在执行查找之前始终知道与键相关联的类型,那么使用多个数据结构可能特别有意义。