c – 消除地图和矢量样容器之间的模板专门化

template<class> struct Printer;

// I want this to match std::vector (and similar linear containers) 
template<template<class,class...> class T,class TV,class... TS> 
    struct Printer<T<TV,TS...>> { ... };

// I want this to match std::map (and similar map-like containers)
template<template<class,class,class...> class TM,class TK,typename... TS> 
    struct Printer<TM<TK,TV,TS...>> { ... }

int main() 
{
    // Both of these match the second specialization,which is only intended
    // for std::map (and similar map-like containers)
    Printer<std::vector<int>>::something();
    Printer<std::map<int,float>>::something();
}

从示例中可以看出,std :: vector和std :: map都匹配第二个专业化.我认为这是因为std :: vector的allocator参数与电视匹配,它适用于std :: map的值.

一个专业版和std :: map(和其他键值容器)第二个如何匹配std :: vector(和其他线性容器)?

解决方法

模式匹配方法的问题是,如果为每个单独的容器编写专门的功能,它只会有效.这是繁琐的工作.

相反,您可以依靠其他属性

>一个容器必然会通过begin(c)和end(c)表达式迭代
>在此之上,关联容器将具有:: key_type嵌套类型,其中包括如第23.2.4节[associative.rqmts]中所表示的.

因此,我们可以根据标签调度来分类

inline constexpr auto is_container_impl(...) -> std::false_type {
    return std::false_type{};
}

template <typename C>
constexpr auto is_container_impl(C const* c) ->
    decltype(begin(*c),end(*c),std::true_type{})
{
    return std::true_type{};
}

template <typename C>
constexpr auto is_container(C const& c) -> decltype(is_container_impl(&c)) {
    return is_container_impl(&c);
}

inline constexpr auto is_associative_container_impl(...)
    -> std::false_type
{ return std::false_type{}; }

template <typename C,typename = typename C::key_type>
constexpr auto is_associative_container_impl(C const*) -> std::true_type {
    return std::true_type{};
}

template <typename C>
constexpr auto is_associative_container(C const& c)
    -> decltype(is_associative_container_impl(&c))
{
    return is_associative_container_impl(&c);
}

现在你可以写“简单”代码

template <typename C>
void print_container(C const& c,std::false_type/*is_associative*/) {
}

template <typename C>
void print_container(C const& c,std::true_type/*is_associative*/) {
}

template <typename C>
void print_container(C const& c) {
    return print_container(C,is_assocative_container(c));
}

现在,这可能不是你想要的,因为在这个要求下,一个集合是一个关联容器,但它的值不是一对,所以你不能打印key:value.您必须根据需要调整标签调度.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...