检查 2 种类型是否具有可比性
Checking whether or not 2 types are comparable
我有以下代码来确定 2 种类型是否具有可比性。
template<typename T, typename U, typename = std::void_t<>>
struct is_comparable
: std::false_type
{};
template<typename T, typename U>
struct is_comparable<T, U, std::void_t<decltype((std::declval<T>() == std::declval<U>()))>>
: std::true_type
{};
这是存档我正在尝试做的事情的可接受方式吗?你能看出这个设计有什么问题吗?
编辑
记住cdhowie的评论和Henri Menki的回答,这就是代码现在的样子。
namespace meta
{
template<typename T, typename U, typename = std::void_t<>>
struct has_equal_to_operator
: std::false_type
{};
template<typename R, typename T, typename U, typename = std::void_t<>>
struct has_equal_to_operator_r
: std::false_type
{};
template<typename T, typename U, typename = std::void_t<>>
struct has_nothrow_equal_to_operator
: std::false_type
{};
template<typename R, typename T, typename U, typename = std::void_t<>>
struct has_nothrow_equal_to_operator_r
: std::false_type
{};
template<typename T, typename U>
struct has_equal_to_operator<T, U, std::void_t<decltype(std::declval<T>() == std::declval<U>())>>
: std::true_type
{};
template<typename R, typename T, typename U>
struct has_equal_to_operator_r<R, T, U, std::void_t<decltype(std::declval<T>() == std::declval<U>())>>
: std::is_convertible<decltype(std::declval<T>() == std::declval<U>()), R>
{};
template<typename T, typename U>
struct has_nothrow_equal_to_operator<T, U, std::void_t<decltype(std::declval<T>() == std::declval<U>())>>
: std::bool_constant<noexcept(std::declval<T>() == std::declval<U>())>
{};
template<typename R, typename T, typename U>
struct has_nothrow_equal_to_operator_r<R, T, U, std::void_t<decltype(std::declval<T>() == std::declval<U>())>>
: std::bool_constant<(noexcept(std::declval<T>() == std::declval<U>()) && std::is_convertible_v<decltype(std::declval<T>() == std::declval<U>()), R>)>
{};
template<typename T, typename U>
inline constexpr auto has_equal_to_operator_v = has_equal_to_operator<T, U>::value;
template<typename R, typename T, typename U>
inline constexpr auto has_equal_to_operator_r_v = has_equal_to_operator_r<R, T, U>::value;
template<typename T, typename U>
inline constexpr auto has_nothrow_equal_to_operator_v = has_nothrow_equal_to_operator<T, U>::value;
template<typename R, typename T, typename U>
inline constexpr auto has_nothrow_equal_to_operator_r_v = has_nothrow_equal_to_operator_r<R, T, U>::value;
}
这是一个解决方案,void_t
就像问题中一样。 此外,我会检查比较是否产生正确的类型(在这种情况下bool
(。
#include <type_traits>
#include <iostream>
template < typename T, typename U >
using equality_comparison_t = decltype(std::declval<T&>() == std::declval<U&>());
template < typename T, typename U, typename = std::void_t<> >
struct is_equality_comparable
: std::false_type
{};
template < typename T, typename U >
struct is_equality_comparable < T, U, std::void_t< equality_comparison_t<T,U> > >
: std::is_same< equality_comparison_t<T,U>, bool >
{};
struct X {};
struct Y { int operator==(Y const&) { return 1; } };
int main()
{
static_assert(false == is_equality_comparable<X, X>(), "!");
static_assert( true == is_equality_comparable<std::string, std::string>(), "!!");
static_assert(false == is_equality_comparable<int, std::string>(), "!!!");
static_assert( true == is_equality_comparable<int, int>(), "!!!!");
static_assert(false == is_equality_comparable<Y, Y>(), "!!!!!");
}
你不远了,但你不需要 C++17:就足够了C++11
#include <type_traits>
#include <iostream>
template <typename T, typename U, typename = void>
struct is_comparable : std::false_type
{};
template <typename T, typename U>
struct is_comparable<T, U,
decltype((std::declval<T>() == std::declval<U>()), void())>
: std::true_type
{};
struct X
{ };
int main()
{
static_assert(false == is_comparable<X, X>(), "!");
static_assert( true == is_comparable<std::string, std::string>(), "!!");
static_assert(false == is_comparable<int, std::string>(), "!!!");
static_assert( true == is_comparable<int, int>(), "!!!!");
}
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 检查 2 种类型是否具有可比性
- 指向虚拟成员函数的指针是否具有可比性