【问题标题】:C++ template specialization between map and multimapmap 和 multimap 之间的 C++ 模板特化
【发布时间】:2017-06-27 10:53:42
【问题描述】:

在这里阅读其他主题我已经编写了检测类是否为关联容器的代码[1]。现在为了使用equal_range,我需要检测它是法线贴图还是多贴图。有什么方法可以实现我的目标吗?

【问题讨论】:

  • std::is_base_of 也许?
  • 所有的 AssociativeContainers(和 UnorderedAssociativeContainers)都有一个 equal_range 成员。为什么需要区分它们?

标签: c++ c++11 templates metaprogramming


【解决方案1】:

您可能会添加自己的类型特征:

template<typename>
struct is_map : std::false_type {};

template<typename K, typename V>
struct is_map<std::map<K, V>> : std::true_type {};

WANDBOX 示例

【讨论】:

  • 遗憾的是,如果您尝试检测从地图继承的类型,这将不起作用。例如: struct MyMap : public std::map{}; is_map 将无法匹配真正的实例化。如果我找到解决方案,我会报告,因为这是我在自己的代码库中需要的。
【解决方案2】:

您也可以根据at()operator[] 的存在,使用the suggestions in this post 进行专业化

【讨论】:

    【解决方案3】:

    原始答案非常适合检查类型是否为地图。但是,它不适用于测试类型是否从映射继承。我对通用解决方案进行了各种尝试,最后我想出了以下代码:

    namespace details {
        constexpr bool is_map(const void*) {
            return false;
        }
    
        template<typename K, typename V, typename Comp, typename Alloc>
        constexpr bool is_map(const std::map<K, V, Comp, Alloc>*) {
            return true;
        }
    }
    
    template<typename T>
    constexpr bool is_map_v = details::is_map(static_cast<const T*>(nullptr));
    
    using map1 = std::map<int, int>;
    static_assert(is_map_v<map1>);
    
    struct MyMap : public std::map<int, int>{};
    static_assert(is_map_v<MyMap>);
    
    static_assert(is_map_v<int> == false);
    

    is_map 函数有 2 个重载。一个匹配指向地图的指针,另一个匹配其他所有内容。因为它们采用指针,所以传递从 map 公开派生的地址也将被接受。

    is_map(const void *) 仅在 T 不可能是地图时才匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      相关资源
      最近更新 更多