如何在C++11中使用
static_assert
来确保模板类型符合EqualityComparable概念?static_assert
来确保模板类型符合EqualityComparable概念?#include <type_traits>
template<typename T, typename = void>
struct is_equality_comparable : std::false_type
{ };
template<typename T>
struct is_equality_comparable<T,
typename std::enable_if<
true,
decltype(std::declval<T&>() == std::declval<T&>(), (void)0)
>::type
> : std::true_type
{
};
struct X { };
struct Y { };
bool operator == (X const&, X const&) { return true; }
int main()
{
static_assert(is_equality_comparable<int>::value, "!"); // Does not fire
static_assert(is_equality_comparable<X>::value, "!"); // Does not fire
static_assert(is_equality_comparable<Y>::value, "!"); // Fires!
}
std :: declval <T>()
而不是T()
。 - jrokdeclval<T&>
还是declval<T>
,都将存在一个“非成语化”的签名,该特征不会正确识别。如果我选择了declval<T>
,那么具有接受可修改的左值引用的operator ==
的类型将被识别为非相等可比较的类型。当然,通过可修改的左值引用进行接受几乎没有意义,但是通过右值引用进行接受甚至更少。 - Andy Prowl
static_assert
有时不是最佳选择。通常情况下,您更希望匹配失败,这需要使用 SFINAE,而不是编译失败,static_assert
会导致编译失败。 - Yakk - Adam Nevraumont