gpt4 book ai didi

c++ - 检查类型是否为 map

转载 作者:可可西里 更新时间:2023-11-01 14:56:44 26 4
gpt4 key购买 nike

我有时发现需要编写可应用于对象容器或此类容器的映射(即处理映射中的每个容器)的通用例程。一种方法是为 map 类型编写单独的例程,但我认为使用一个适用于两种输入类型的例程会更自然、更简洁:

template <typename T>
auto foo(const T& items)
{
return foo(items, /* tag dispatch to map or non-map */);
}

执行此标记分派(dispatch)的安全、干净的方法是什么?

最佳答案

现有答案针对 std::map 的非常具体的属性进行测试, 或者它恰好是 std::map 的特化(这对于 std::unordered_map 或与 std::map 具有相同接口(interface)的非标准类型来说是假的),或者测试它的 value_type正是std::pair<const key_type, mapped_type> (这对于 multimapunordered_map 是正确的,但对于具有相似接口(interface)的非标准类型是错误的)。

这只测试它提供的 key_typemapped_type成员,并且可以通过 operator[] 访问,所以不说 std::multimap是mappish:

#include <type_traits>

namespace detail {
// Needed for some older versions of GCC
template<typename...>
struct voider { using type = void; };

// std::void_t will be part of C++17, but until then define it ourselves:
template<typename... T>
using void_t = typename voider<T...>::type;

template<typename T, typename U = void>
struct is_mappish_impl : std::false_type { };

template<typename T>
struct is_mappish_impl<T, void_t<typename T::key_type,
typename T::mapped_type,
decltype(std::declval<T&>()[std::declval<const typename T::key_type&>()])>>
: std::true_type { };
}

template<typename T>
struct is_mappish : detail::is_mappish_impl<T>::type { };

因为 is_mappish具有 true_type 的“基本特征”或 false_type你可以像这样调度它:

template <typename T>
auto foo(const T& items, true_type)
{
// here be maps
}

template <typename T>
auto foo(const T& items, false_type)
{
// map-free zone
}

template <typename T>
auto foo(const T& items)
{
return foo(items, is_mappish<T>{});
}

或者你可以避免完全调度,只是重载 foo对于 map 和非 map :

template <typename T,
std::enable_if_t<is_mappish<T>{}, int> = 0>
auto foo(const T& items)
{
// here be maps
}

template <typename T,
std::enable_if_t<!is_mappish<T>{}, int> = 0>
auto foo(const T& items)
{
// map-free zone
}

关于c++ - 检查类型是否为 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35293470/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com