C++ 检查 std::array 或 unordred_map/map 包含相同的元素类型

C++ check std::array or unordred_map/map contain same element type

我有一个模板 class 接受 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<something, MyIDType>

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

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

有多种方法可以实现您想要的效果。最简单的(前提是你只有两种类型)似乎是通过 helper struct:

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,但既然你提到你只需要两个,这似乎有点过分了。

What is the best way to check for MyIDType for both std::array and std::unordered_map?

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

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;
};

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

// 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