Я делал общий алгоритм хеширования для std::tuple
и понял, что могу заставить его работать и для std::pair
и std::array
, так как эти три класса реализуют std::tuple_size
и std::get
. Это "стандартизировано" где-нибудь? Есть ли "std::allocator_traits
", но для классов, похожих на std :: tuple, вместо классов, похожих на std :: allocator?
В настоящее время я делаю это, чтобы проверить, является ли класс "кортежным":
#include <type_traits>
#include <cstddef>
#include <utility>
#include <tuple>
namespace is_tuple {
namespace detail {
// T* exists for incomplete types, but not sizeof(T)
template<class T, ::std::size_t = sizeof(T)>
::std::true_type is_complete_type_impl(T*);
::std::false_type is_complete_type_impl(...);
template<class T>
struct is_complete_type : decltype(
is_complete_type_impl(::std::declval<T*>())
) {};
}
template<class T>
struct is_tuple : detail::is_complete_type<::std::tuple_size<T>>::type {};
}
Это может иметь некоторый ложный положительный результат (хотя я не думаю, что это так)
Это «требования», которые я навязываю для «кортежоподобных» типов, для типа T
и объекта типа T
с именем t
:
std::tuple_size<T>
- полный тип
std::tuple_size<T>::value
- это static constexpr const std::size_t
(называется N
)
std::get<I>(t)
возвращает недействительные для всех I
в [0
, N
)
(Это правильно и полно? Я также включил проверку std::get
, но код был слишком длинным для отправки)
А также, есть ли лучший способ указать, является ли тип "кортежным", кроме специализации std::tuple_size<T>
(может быть, что-то вроде iterator_tag)