我想实现一个地图,它将字符串映射到通用矢量。
我想这样做:
std::map<std::string, std::vector<class T> > myMap;
假设建议的myMap插入了以下内容,它可以这样使用:
vector<int> intVec = myMap["ListOfInts"]; // Works because "ListOfInts" maps to a vector<int>
vector<string> stringVec = myMap["ListOfStrings"]; // Works because "ListOfInts" maps to a vector<string>
当我使用上述语法声明地图时,编译器会发生心脏病发作。
有人可以提出任何建议吗?或者是C ++中更好的关联数组选项(建议在提升之前不加速)。
答案 0 :(得分:2)
由于您在编写代码时知道所需的类型,因此我提出了这种方法(未经测试):
// base class for any kind of map
class BaseMap {
public:
virtual ~BaseMap() {}
};
// actual map of vector<T>
template<typename T>
class MapT : public BaseMap, public std::map<std::string, std::vector<T>> {};
class MultiMap {
public:
template<typename T>
std::vector<T>& get(const std::string& key) {
std::unique_ptr<BaseMap>& ptr = maps_[std::type_index(typeid(T))];
if (!ptr) ptr.reset(new MapT<T>());
return ptr->second[key];
}
private:
std::map<std::type_index, std::unique_ptr<BaseMap>> maps_;
}
int main() {
MultiMap map;
std::vector<int>& intVec = map.get<int>("ListOfInts");
std::vector<std::string>& stringVec = map.get<std::string>("ListOfStrings");
}
答案 1 :(得分:0)
也许这对你有用:
template <typename T>
class MyMap {
std::map<std::string, std::vector<typename T> > map;
public:
/*...*/
};
答案 2 :(得分:0)
使用C ++ 11,您可以使用using
,它完全符合您的要求:
#include <vector>
#include <map>
#include <string>
template<typename T> using mymap = std::map<std::string, std::vector<T>>;
int main()
{
mymap<int> intmap;
mymap<std::string> stringmap;
std::vector<int> intvec = intmap["test"];
std::vector<std::string> stringvec = stringmap["test"];
return 0;
}
答案 3 :(得分:0)
正如mattnewport所说,boost::variant
是一种选择。
或支持任何类型,请使用boost::any
明确使用any_cast
。
考虑到提升可能是重量级的,也许你可以重新发明轮子并简化它,这样就不再提升了?洛尔
答案 4 :(得分:-2)
模板参数必须在编译时确定。如果您希望地图中的每个键对应一个不同类型的矢量,那么它将无法真正发挥作用。你可以使用一个多态容器来解决它,它返回一个你投射到正确类型的void *,但是我建议你先找另一种方法来做你想做的事情。