有一种方法有异构映射在c++ ?



是否有办法使heterogeneous地图实现如下所示,请满足以下条件:

  1. 类型在运行时已知,以及读取键。
  2. 几乎零开销,例如,boost::any不是我的目的,这是缓慢的。
  3. 没有丑陋的长宏。
class special_map;
class buffer
{
public:
~buffer() = default;
buffer(const special_map& map) : m_map(map) {};
template<typename T>
void read(const std::string& name, T& value)
{
map.read<T>(name, value);
return void();
}
private:
special_map m_map;
};

我可以使用:

  1. void*reinterpret_cast好吗?如何?它对客户端/用户安全吗?
  2. 我可以使用boost::hanaboost::fusion

谢谢你。(请参见条件)

这是一个内部使用std::map(或任何您选择的映射实现)的T类型,我们希望能够存储的实现。从评论中,我读到我们知道我们想要存储什么类型。我期望这个实现的开销与底层映射实现大致相同,但是测试它不是我的工作。在此实现中没有古怪的指针强制转换或使用std::variant等:

#include <map>
template <typename ... T> class special_map {};
template <> class special_map<> {};
template <typename T, typename ... Args> struct MapAccess {};
template <typename T, typename First, typename ...Rest>
struct MapAccess<T, First, Rest...> {
typedef MapAccess<T, Rest...> Next;

static T read(special_map<First, Rest...>* m, const std::string& k) {
return Next::read(&(m->rest), k);
}
static void write(special_map<First, Rest...>* m, const std::string& k, const T& v) {
Next::write(&(m->rest), k, v);
}
};
template <typename T, typename ... Rest>
struct MapAccess<T, T, Rest...> {
static T read(special_map<T, Rest...>* m, const std::string& k) {
return m->storage.at(k);
}

static void write(special_map<T, Rest...>* m, const std::string& k, const T& v) {
m->storage[k] = v;
}
};
template <typename First, typename ... Rest>
struct special_map<First, Rest...> {
special_map<Rest...> rest;
std::map<std::string, First> storage;

template <typename T>
void write(const std::string& k, const T& v) {
MapAccess<T, First, Rest...>::write(this, k, v);
}

template <typename T>
void read(const std::string& k, T& v) {
v = MapAccess<T, First, Rest...>::read(this, k);
}
};

所以要使用它,你必须列出它应该能够存储的所有类型,例如

special_map<float, int, std::string> myMap;

如果您尝试将其与未在该列表中列出的类型一起使用,我希望您会得到一个有趣的编译错误,因此您将知道您必须在那里添加它:-)例如,如果我尝试从myMap读取bool,我会得到错误

main.cpp:15:22: error: ‘read’ is not a member of ‘MapAccess<bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::Next’ {aka ‘MapAccess<bool>’}

最新更新