【问题标题】:C++ check std::array or unordred_map/map contain same element typeC++ 检查 std::array 或 unordred_map/map 是否包含相同的元素类型
【发布时间】:2020-11-19 06:20:32
【问题描述】:

我有一个模板类接受 MyIDType 的容器:

  • std::array<MyIDType, SIZE>
  • std::unordered_map<A, MyIDType>
  • std::unordered_map<B, MyIDType>

我想静态断言 MyIDType 是元素。我试过这个:

template<class CONTAINER>
class Cod
{
    using ELEMENT_TYPE = typename CONTAINER::value_type;
    static_assert(std::is_same<ELEMENT_TYPE, MyIDType>::value);

但意识到它会失败,因为std::unordered_map 的值类型实际上是std::pair&lt;something, MyIDType&gt;

std::arraystd::unordered_map 检查MyIDType 的最佳方法是什么?

地图有mapped_type,但是当我传入数组时显然不会编译。

【问题讨论】:

  • 你打算只支持两种容器类型吗?
  • if constexpr 或静态断言中更长的或表达式。
  • @SergeyA 是的,只有这两个,但地图的键类型可能会改变。
  • 你想要std::unordered_map::mapped_type

标签: c++ arrays templates types unordered-map


【解决方案1】:

你可以定义一个类型特征,比如

// primary template, for types containing value_type
template <typename T, typename = void>
struct get_element_type {
    using type = typename T::value_type;
};
// partial specialization, for types containing mapped_type
template <typename T>
struct get_element_type<T, std::void_t<typename T::mapped_type>> {
    using type = typename T::mapped_type;
};

然后

template<class CONTAINER>
class Cod
{
    using ELEMENT_TYPE = typename get_element_type<CONTAINER>::type;
    static_assert(std::is_same<ELEMENT_TYPE, MyIDType>::value);

LIVE

【讨论】:

  • 这适用于 cpp17 吗?我在使用 type = typename T::value_type; 时遇到错误它需要一个表达式,其中“使用”是
  • @user997112 抱歉,我错过了&gt;,答案已修改。是的,std::void_t 需要 C++17。如果您的编译器不支持 C++17,您可以制作自己的替代品。
  • 不需要道歉!那么“使用类型”这一行,实际上是“返回”到使用 ELEMENT_TYPE = typename get_element_type 的调用吗?
  • @user997112 是的,它是用来定义嵌套类型的,那么我们可以像get_element_type&lt;...&gt;::type一样使用它。
【解决方案2】:

有几种方法可以实现您想要的。最简单的(假设你只有两种类型)似乎是通过辅助结构:

template<class CONTAINER>
struct ElementType {
    using type = typename CONTAINER::mapped_type;
};

template<class T, size_t SZ>
struct ElementType<std::array<T, SZ>> {
    using ElementType = T;
};

而且你可以在 ElementType 上断言。还有其他方法,允许根据mapped_type 的存在选择性地使用mapped_typevalue_type,但既然你提到你只需要两个,这似乎有点矫枉过正。

【讨论】:

    【解决方案3】:

    为 std::array 和 std::unordered_map 检查 MyIDType 的最佳方法是什么?

    您可以使用类型特征的模板特化:

    template<class Container>
    struct fancy_element_trait {
        using type = typename Container::value_type;
    };
    
    template<class ... Args>
    struct fancy_element_trait<std::unordered_map<Args...>> {
        using type = typename std::unordered_map<Args...>::mapped_type;
    };
    

    【讨论】:

      猜你喜欢
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 2021-10-21
      • 1970-01-01
      • 2018-04-22
      • 2011-08-19
      相关资源
      最近更新 更多