实现一个C++,它支持任何类型的键的2级外观
Implement a C++ which supports 2 level looks with keys of any type
我需要实现一个C++类来支持以下
数据:
密钥字符串
子密钥-字符串/双
值-字符串/双
键&子键一起唯一地标识行。
例如:
[ "key", "subkey", "value" ]
[ "cse", "a", 100 ]
[ "cse", "b", 120 ]
[ "cse", 100, 10 ]
操作:
1( 给定一个键&返回值
2( 给定一个密钥返回一个[ "subkey", "value" ]
数组
我面临的问题是,子键和值既可以是双精度的,也可以是字符串。解决这个问题的一种方法是拥有一个包装器类,该类能够存储double和string类型。
第一级映射将有一个字符串作为键,值将是一个映射。
第二级映射将具有作为新包装器类的键,并且value也是一个新的包装器类。
这种方法正确吗?或者有更好的方法吗?
我用Boost.Variant和C++11 unordered_map
破解了一个解决方案。该代码是一个非常好的例子,适用于C++11。
你需要特别注意这两个散列的组合在std::hash<key>::operator()
的专业化中,它可以具有强烈影响哈希的质量。为了更好地实施看看boost::hash_combine
,遗憾的是它还没有标准化。
一般来说,代码的作用是:定义一个特殊的键类型EqualityComparable和Hashable,然后在std::unordered_map
。你可以用Boost和no来构建所有这些C++11。如果你既没有Boost也没有C++11,你就陷入了困境斑点没有对此进行真正的测试。
#include <boost/variant.hpp>
#include <string>
#include <functional>
#include <unordered_map>
#include <iostream>
struct key {
std::string primary;
boost::variant<std::string, double> secondary;
friend bool operator==(const key& x, const key& y)
{ return x.primary == y.primary && x.secondary == y.secondary; }
};
namespace std {
template<>
struct hash<key> {
std::size_t operator()(const key& k) const
{
std::size_t first = std::hash<std::string>()(k.primary);
std::size_t second;
// check for the more likely case first
if(const std::string* s = boost::get<std::string>(&(k.secondary))) {
second = std::hash<std::string>()(*s);
} else {
const double* d = boost::get<double>(&(k.secondary));
second = std::hash<double>()(*d);
}
return first ^ ( second << 1 ); // not so fancy hash_combine
}
};
} // std
int main()
{
typedef std::unordered_map<key, boost::variant<std::string, double>> MyMap;
MyMap m = {
{{"foo", "bar"}, "foobar"},
{{"foo", 23.0}, "foo23"},
{{"nothing", 23.0}, 23.0}
};
std::cout << m[{"foo", "bar"}] << std::endl;
std::cout << m[{"foo", 23.0}] << std::endl;
std::cout << m[{"nothing", 23.0}] << std::endl;
return 0;
}
以下每个键浪费了一点空间,但具有简单的优点:
struct Key
{
Key(string primary, string subkey)
: primary(primary)
, is_double(false)
, string_subkey(subkey)
{}
Key(string primary, double subkey)
: primary(primary)
, is_double(true)
, double_subkey(subkey)
{}
string primary;
bool is_double;
double double_subkey;
string string_subkey;
}
您需要实现适当的比较操作和/或散列函数。
相关文章:
- 缺少类型说明符 - 假定为 int.注意 c++ 不支持 default-int
- 错误:C4430:缺少类型说明符-假定为int.注意:C++不支持default-int
- boost odeint 中的受控误差步进器是否支持复杂的数据类型?
- 如何获取具有 Freetype2 的真正类型字体支持的代码点列表 C++
- 如何根据基类型支持不同数量的参数?
- C++11: Atomic::compare_exchange_weak 是否支持非基元类型?
- boost multi_index - 如果元素类型仅支持移动语义,如何遍历它?
- 支持按值传递语句的示例不是很好的做法,即使对于小型用户定义类型也是如此
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- C++:“enable_if”用于限制支持特定算术运算的类型
- 在支持多种类型的宏中使用printf
- 如何获得支持枚举的类型
- 错误C4430:丢失类型指定词 - 假设INT.注意:C 不支持对我的构造函数的默认设置
- 是否可以在编译时测试类型是否支持负零C++
- 自动复制=按值并支持多态性的适当类型的非静态字段
- OpenCV错误:不支持的格式或格式组合(Point3f类型的点的矢量的矢量)
- 防止为字符串流提取运算符不支持的类型实例化模板类 (>>)
- cin和cout如何支持不同的数据类型
- 为什么 std::bitset 只支持整型数据类型?为什么不支持浮点数?
- CORBA 类型支持,始终附加 :1.0