首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板参数,也接受模板(嵌套模板)

模板参数,也接受模板(嵌套模板)
EN

Stack Overflow用户
提问于 2016-05-11 17:12:24
回答 3查看 121关注 0票数 0

我试图避免代码重复,原因如下:

代码语言:javascript
复制
template<class StringType, typename type1, typename type2, class MapType>
void readDatastructure(MapType<type1, type2> map, const StringType path) {
... some code
}

我有几种不同的映射类型,它们具有不同的type1type2参数。在某种程度上,我想静态地检查哪些类型是type1type2,但是我不知道如何编译这个东西。我试过了几个模板声明的变体,它们似乎都不起作用。这可能吗?

干杯,

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-11 17:15:22

你想要的东西

代码语言:javascript
复制
template<class StringType, typename type1, typename type2,
         template<class, class> class MapType>
void readDatastructure(MapType<type1, type2> map, const StringType path);

但是这不适用于,比方说,std::map,它有两个额外的模板参数(对于比较器和分配器)。所以你要么去做

代码语言:javascript
复制
template<class StringType, typename type1, typename type2,
         template<class...> class MapType>
void readDatastructure(MapType<type1, type2> map, const StringType path);

或者添加额外的模板参数,即,

代码语言:javascript
复制
template<class StringType, typename type1, typename type2, class C, class A,
         template<class, class, class, class> class MapType>
void readDatastructure(MapType<type1, type2, C, A> map, const StringType path);

第一种方法仍然不适用于采用非默认比较器/分配器的std::map;第二种方法是,如果您的映射没有精确的四个模板类型参数,例如unordered_map,它有5个,则无法工作。

因此,最好让您的映射类型发布这些类型。例如,std::map将它们发布为key_typemapped_type。所谓“发布”,我的意思是将它们定义为成员类型。然后你可以写

代码语言:javascript
复制
template<class StringType, class MapType>
void readDatastructure(MapType map, const StringType path);

并使用例如,typename MapType::key_type代替type1

如果您不能更改您的映射类型,并且它们不遵循标准协议,则可以编写一个特性类并将其专门用于您的映射类型:

代码语言:javascript
复制
template<class T>
struct map_traits {
    using key_type = typename T::key_type;
    using mapped_type = typename T::mapped_type;
};
template<class T1, class T2>
struct map_traits<MyBrokenMap<T1, T2>> {
    using key_type = T1;
    using mapped_type = T2;
};

然后你可以使用typename map_traits<MapType>::key_type等。

票数 3
EN

Stack Overflow用户

发布于 2016-05-11 17:16:20

模板参数

代码语言:javascript
复制
template<class StringType, typename type1, typename type2, template <typename, typename > class MapType>
票数 1
EN

Stack Overflow用户

发布于 2016-05-11 18:51:34

所有std::map类型定义类型key_typemapped_type

编写一个is_map特性来约束模板函数扩展是很简单的。

示例:

代码语言:javascript
复制
#include <iostream>
#include <map>
#include <unordered_map>
#include <utility>
#include <typeinfo>


template<class Map> struct is_map
{
    static constexpr bool value = false;
};

template<class K, class V, class Comp, class Alloc>
struct is_map<std::map<K, V, Comp, Alloc>>
{
    static constexpr bool value = true;
};

template<class K, class V, class Comp, class Hash, class Alloc>
struct is_map<std::unordered_map<K, V, Comp, Hash, Alloc>>
{
    static constexpr bool value = true;
};

template<
class Map,
class String,
std::enable_if_t<is_map<Map>::value>* = nullptr
>
void readDataStructure(Map& map, String&& path)
{
    std::cout << "reading map with key type: " << typeid(typename Map::key_type).name() << std::endl;
    std::cout << "      and with value type: " << typeid(typename Map::mapped_type).name() << std::endl;
    std::cout << "--------------------------"  << std::endl;
}


int main()
{
    std::map<int, std::string> m1;
    std::unordered_map<int, std::wstring> m2;
    readDataStructure(m1, "foo.txt");
    readDataStructure(m2, "foo.txt");
}

示例输出:

代码语言:javascript
复制
reading map with key type: i
      and with value type: NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
--------------------------
reading map with key type: i
      and with value type: NSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE
--------------------------
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37169224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档