std::tuple-like 的命名要求? [英] Named requirement for std::tuple-like?
问题描述
我正在为 std::tuple
制作一个通用哈希算法,并意识到我可以让它适用于 std::pair
和 std::array
也是如此,因为这三个类实现了 std::tuple_size
和 std::get
.这是标准化"的地方吗?是否有std::allocator_traits
"但对于 std::tuple-like 类而不是 std::allocator-like 类?
I was making a generic hash algorithm for std::tuple
, and realised I could make it work for std::pair
and std::array
as well, as these three classes implement std::tuple_size
and std::get
. Is this "standardised" anywhere? Is there a "std::allocator_traits
" but for std::tuple-like classes instead of std::allocator-like classes?
目前我这样做是为了检查一个类是否是类元组":
Currently I am doing this to check if a class is "tuple-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 {};
}
这可能有一些误报(尽管我认为不会)
This might have some false positive (though I don't think it does)
这些是我对类元组"类型、类型 T
和名为 t<的
T
类型的对象强加的要求"/代码>:
These are the "requirements" I am imposing for "tuple-like" types, for a type T
and an object of type T
called t
:
std::tuple_size
是一个完整的类型std::tuple_size
是一个::value static constexpr const std::size_t
(称为N
)std::get(t)
为 [0
,N<中的所有
I
返回非空值/code>)
std::tuple_size<T>
is a complete typestd::tuple_size<T>::value
is astatic constexpr const std::size_t
(calledN
)std::get<I>(t)
returns non-void for allI
in [0
,N
)
(这是否正确和完整?我也实现了检查std::get
,但代码太长无法发布)
(Is this correct and complete? I also implemented checking std::get
, but the code was too long to post)
此外,除了专门化 std::tuple_size
(可能类似于 iterator_tag)
And also, is there a better way to specify if a type is "tuple-like" other than specialising std::tuple_size<T>
(Something like an iterator_tag maybe)
推荐答案
这在任何地方都标准化"了吗?
Is this "standardised" anywhere?
如果你指的是散列算法,那么(像很多事情一样)在 boost
中已经有一个完整的解决方案.
If you mean the hash algorithm, then (like so many things) there is already a complete solution in boost
.
boost
当然可以说比 C++ 的各种实现更标准化,当然更便携标准本身.1
boost
is of course, arguably more standardised and certainly more portable than the various implementations of the c++ standard itself.1
#include <boost/functional/hash.hpp>
#include <tuple>
#include <utility>
#include <array>
#include <string>
#include <iostream>
template<class T>
std::size_t hashit(T const& x)
{
using x_type = std::decay_t<T>;
return boost::hash<x_type>()(x);
}
template<class T>
std::size_t hashit2(T const& x)
{
using boost::hash_value;
return hash_value(x);
}
int main()
{
using namespace std::literals;
std::cout << hashit(std::make_tuple(1, 2, 5, "foo"s)) << '\n';
std::cout << hashit2(std::make_tuple(1, 2, 5, "foo"s)) << '\n';
std::cout << '\n';
std::cout << hashit(std::make_pair(1.0, 2.0)) << '\n';
std::cout << hashit2(std::make_pair(1.0, 2.0)) << '\n';
std::cout << '\n';
std::cout << hashit(std::array<int, 3>{4, 5, 6}) << '\n';
std::cout << hashit2(std::array<int, 3>{4, 5, 6}) << '\n';
}
1 这将被许多人视为有争议的声明.尽管如此,它在经验上是正确的.
1 This will be seen by many as a controversial statement. It is nonetheless empirically true.
这篇关于std::tuple-like 的命名要求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!