Các kiểm tra câu trả lời hiện tại cho các tính chất rất cụ thể của std::map
, hoặc là nó chính xác là một chuyên môn của std::map
(điều này sẽ sai cho std::unordered_map
hoặc các loại không chuẩn với cùng một giao diện như std::map
) hoặc kiểm tra rằng value_type
chính xác là std::pair<const key_type, mapped_type>
(điều này đúng với multimap
và unordered_map
, nhưng sai cho các loại không chuẩn với giao diện tương tự).
này chỉ kiểm tra mà nó cung cấp key_type
và mapped_type
thành viên, và có thể được truy cập với operator[]
, vì vậy không nói rằng std::multimap
là 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 { };
Vì is_mappish
có một "cơ sở đặc trưng" của một trong hai true_type
hoặc false_type
bạn có thể gửi về nó như vậy:
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>{});
}
hoặc bạn có thể tránh cử hoàn toàn, và chỉ tình trạng quá tải foo
cho bản đồ và không phải bản đồ:
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
}
Nguồn
2016-02-09 13:59:35
Kiểm tra xem nó có lồng nhau loại 'key_type' và' mapped_type' không? –