I have this code: https://ideone.com/dUkfjp
#include <type_traits>
namespace details
{
template <typename T, typename U = T>
using equality_compare_ret_t = decltype(std::declval<T>() == std::declval<U>());
template <typename T, typename U = T>
using not_equality_compare_ret_t = decltype(std::declval<T>() != std::declval<U>());
};//end namespace details
template <typename, typename = std::void_t<>>
struct is_equality_comparable
: std::false_type
{};
template <typename T>
struct is_equality_comparable<T,
std::void_t<
details::equality_compare_ret_t<std::remove_reference_t<T>>,
details::not_equality_compare_ret_t<std::remove_reference_t<T>>
>>
: std::true_type
{};
template <typename T>
constexpr bool is_equality_comparable_v = is_equality_comparable<T>::value;
struct default_constuctible
{
constexpr default_constuctible()
{}
};
bool operator==(const default_constuctible&, const default_constuctible&)
{
return true;
}
bool operator!=(const default_constuctible&, const default_constuctible&)
{
return false;
}
static_assert(is_equality_comparable<default_constuctible>::value, "false");
Compiles with defaults on ideone C++14 (gcc 6.3)
The same code in godbolt.org compiles with clang 6.0.0 and gcc 8.1 and don't compiles with MSVC 19 2017 RTW.
Don't compiles because of the last line code:
static_assert(is_equality_comparable<default_constuctible>::value, "false");
In MSVC is_equality_comparable<default_constuctible>::value
is evaluated as false and in clang/gcc is evaluted as true. Same problem I have in MSVC 2017 community edition 15.7.3.
I don't understand why, bug in MSVC or in my code?
fixed with
template <typename T>
using equality_compare_ret_t = decltype(std::declval<T>() == std::declval<T>());
template <typename T>
using not_equality_compare_ret_t = decltype(std::declval<T>() != std::declval<T>());
better solution (compiles in vc++ 15.7.3, doesn't compile in msvc 19 2017 rtw):
#include <type_traits>
namespace details
{
template <typename T, typename U>
using equality_compare_with_ret_t = decltype(std::declval<T>() == std::declval<U>());
template <typename T, typename U>
using not_equality_compare_with_ret_t = decltype(std::declval<T>() != std::declval<U>());
template <typename T>
using equality_compare_ret_t = decltype(std::declval<T>() == std::declval<T>());
template <typename T>
using not_equality_compare_ret_t = decltype(std::declval<T>() != std::declval<T>());
};//end namespace details
template <typename, typename, typename = std::void_t<>>
struct is_equality_comparable_with
: std::false_type
{};
template <typename T, typename U>
struct is_equality_comparable_with<T, U,
std::void_t<
details::equality_compare_with_ret_t<std::remove_reference_t<T>, std::remove_reference_t<U>>,
details::not_equality_compare_with_ret_t<std::remove_reference_t<T>, std::remove_reference_t<U>>
>>
: std::true_type
{};
template <typename T, typename U>
constexpr bool is_equality_comparable_with_v = is_equality_comparable_with<T, U>::value;
template <typename, typename = std::void_t<>>
struct is_equality_comparable
: std::false_type
{};
template <typename T>
struct is_equality_comparable<T,
std::void_t<
details::equality_compare_ret_t<std::remove_reference_t<T>>,
details::not_equality_compare_ret_t<std::remove_reference_t<T>>
>>
: std::true_type
{};
template <typename T>
constexpr bool is_equality_comparable_v = is_equality_comparable<T>::value;
struct default_constuctible
{
constexpr default_constuctible()
{}
};
bool operator==(const default_constuctible&, const default_constuctible&)
{
return true;
}
bool operator!=(const default_constuctible&, const default_constuctible&)
{
return false;
}
bool operator==(const default_constuctible&, int)
{
return true;
}
bool operator!=(const default_constuctible&, int)
{
return false;
}
static_assert(is_equality_comparable<default_constuctible>::value, "false");
static_assert(is_equality_comparable_with<default_constuctible, int>::value, "false");
static_assert(!is_equality_comparable_with<default_constuctible, char*>::value, "false");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.