Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从一组字典返回泛型容器_C++_Templates - Fatal编程技术网

C++ 从一组字典返回泛型容器

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<

我有一个字典集合(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<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内部搜索,但我不知道如何实现这一点,因为我不能仅通过返回类型重载函数。