【发布时间】:2019-01-08 21:50:34
【问题描述】:
我正在为std::tuple 制作一个通用哈希算法,并意识到我也可以让它适用于std::pair 和std::array,因为这三个类实现了std::tuple_size 和std::get。这在任何地方都“标准化”了吗?是否有一个“std::allocator_traits”但对于 std::tuple-like 类而不是 std::allocator-like 类?
目前我这样做是为了检查一个类是否“类似元组”:
#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)为 [0,N) 中的所有I返回非 void
(这是否正确完整?我也实现了检查std::get,但代码太长,无法发布)
此外,除了专门化 std::tuple_size<T> (可能是 iterator_tag 之类的东西)之外,是否有更好的方法来指定类型是否是“类元组”
【问题讨论】:
-
检查
std::get<i>应该检查get<i>,因为应通过ADL 找到候选人 -
std::tuple_element可能会丢失(例如,结构化绑定需要)(并且允许处理引用类型:std::get<0>(std::tie(lvalue))和std::get<0>(std::make_tuple(lvalue))都返回引用类型)。 -
@GuillaumeRacicot:
t.get<I>()也可以用于structured_binding。