我当时正在为std::tuple
开发一种通用的哈希算法,并意识到我也可以使其适用于std::pair
和std::array
,因为这三个类实现了std::tuple_size
和std::get
。这在任何地方都“标准化”了吗?除了类std :: tuple的类而不是类std :: allocator的类,是否有一个“ std::allocator_traits
”?
目前,我正在这样做,以检查类是否为“类似元组”:
#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之类的东西)之外,还有一种更好的方法来指定类型是否为“元组式”
答案 0 :(得分:0)
这个“标准化”在任何地方吗?
如果您指的是哈希算法,那么boost
中已经有一个完整的解决方案。
boost
当然可以说是更加标准化和肯定地更具可移植性。 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 这将被许多人视为有争议的陈述。尽管如此,从经验上讲它是正确的。