C++ 从一组字典返回泛型容器
我有一个字典集合(std::maps),它将通用容器Foo与唯一ID一起存储。给定这样一个唯一ID,我想返回相应的容器。但我现在还不知道具有给定ID的Foo对象存储在哪个dict中,所以下面是一行:C++ 从一组字典返回泛型容器,c++,templates,C++,Templates,我有一个字典集合(std::maps),它将通用容器Foo与唯一ID一起存储。给定这样一个唯一ID,我想返回相应的容器。但我现在还不知道具有给定ID的Foo对象存储在哪个dict中,所以下面是一行: #include <map> std::map<ID, Foo<double>> mapDouble; std::map<ID, Foo<int>> mapInt; template <class T> Foo<
#include <map>
std::map<ID, Foo<double>> mapDouble;
std::map<ID, Foo<int>> mapInt;
template <class T>
Foo<T> getVal(ID id) {
std::map<ID, Foo<double>>::iterator itDoub = mapDouble.find(id);
if(itDoub != mapDouble.end()) {
return = itDoub->second;
}
std::map<ID, Foo<int>>::iterator itInt = mapInt.find(id);
if(itInt!= mapInt.end()) {
return = itInt->second;
}
}
void bar() {
Foo<int> foo getVal<int>(3);
}
#包括
std::map-double;
std::mapInt;
模板
Foo getVal(ID){
std::map::迭代器itDoub=mapDouble.find(id);
if(itDoub!=mapDouble.end()){
return=itDoub->second;
}
std::map::iterator itInt=mapInt.find(id);
如果(itInt!=mapInt.end()){
return=itInt->second;
}
}
空条(){
福福格瓦尔(3);
}
但是我得到了下面的错误消息
error: no viable conversion from 'Foo <double>' to 'Foo <int>'
错误:从'Foo'到'Foo'没有可行的转换
这当然是完全有道理的。
但实现此功能的正确方法是什么?
我想我在这里实现的是某种工厂。您的问题是类型参数(
)和成员名称(mapInt
)之间没有良好的连接
解决方案是找到一些不使用成员的方法-最简单的方法是:
#include <map>
typedef int ID;
template <typename T> struct Foo {};
class MapContainer {
std::map<ID, Foo<double>> mapDouble;
std::map<ID, Foo<int>> mapInt;
template <typename T> std::map<ID, Foo<T>>& getmap();
public:
template <class T>
Foo<T> getVal(ID id) {
auto &map = getmap<T>();
auto it = map.find(id);
if(it != map.end()) {
return it->second;
} else {
return Foo<T>{}; // ???
}
}
};
template <> std::map<ID, Foo<double>>& MapContainer::getmap() { return mapDouble; }
template <> std::map<ID, Foo<int>>& MapContainer::getmap() { return mapInt; }
#包括
typedef int-ID;
模板结构Foo{};
类映射容器{
std::map-double;
std::mapInt;
模板std::map&getmap();
公众:
模板
Foo getVal(ID){
auto&map=getmap();
autoit=map.find(id);
if(it!=map.end()){
返回->秒;
}否则{
返回Foo{};//???
}
}
};
模板std::map&MapContainer::getmap(){return mapDouble;}
模板std::map&MapContainer::getmap(){return mapInt;}
这里,类型和成员名称之间的连接由模板方法专门化(getmap
)处理
请注意,对于不支持的类型,这当前会导致链接器错误。通过定义泛型getmap,使其在实例化时失败,可以获得稍微友好的错误消息
一个更麻烦但可能更令人满意的解决方案(也可以更好地扩展和泛化到更多类型)是完全消除命名数据成员,并使用泛型类型来代替容器查找。例如,一组元组可以用元素类型代替位置查询(参见现代C++设计/洛基),而Booost。Fusion提供了你想要的异构集合。 <代码> GETVAL < /C>只应在代码> MAPITN<代码>内搜索。如果没有找到密钥,会发生什么?@ JAROD42。“保证”对应的对象是registered@Jarod42我同意getVal应该只在mapInt内部搜索,但我不知道如何实现这一点,因为我不能仅通过返回类型重载函数。