Explanation
Let's break it down step-by-step:
(T*)(0) : pretend there's an object of type T at address 0; the type of this subexpression is a pointer
*(T*)(0) : pretend there's an object of type T at address 0; the type of this subexpression is a reference, due to the asterisk in front dereferencing the pointer. It looks kind of like a null pointer dereference, but more on that later.
*(Arg*)(0) : pretend there's an object of type Arg at address 0; same pattern as T
*(T*)(0) == *(Arg*)(0) : this is equivalent to calling operator==<T, Arg>( *(T*)(0), *(Arg*)(0) ) with the additional convenience of letting the compiler figure out where the operator is defined.
- If a user-defined
operator== does not exist, then the CHECK namespace operator will be matched instead. It's a "catch all" template.
decltype(*(T*)(0) == *(Arg*)(0)) : decltype says "don't execute the subexpression in the parentheses; just give me its type". In this case, the type is the return type of the operator== call.
- No comparison operation actually occurs, nor any derefences into memory.
std::is_same<decltype(*(T*)(0) == *(Arg*)(0)), No>::value : std::is_same's value is true if the types are identical, or false otherwise.
::value is a static constexpr bool
- The two type arguments are the
decltype(...) and struct CHECK::No.
- A real-world
operator== typically returns bool. Occasionally it may return a user-defined type. It's unlikely that someone will write their custom operator== to return CHECK::No, and this code is relying upon that assumption.
enum { value = !std::is_same<...>::value } : An enum is always a compile-time constant, works on older C++ compilers & specs (like C++03, where constexpr didn't exist), is compatible with constexpr, and does not require storage.
static constexpr bool value = !std::is_same<...>::value; would have been equivalent.
Issues with the example code:
- Technically it's illegal to dereference a null pointer;
std::declval is a safe alternative.
- Technically someone could write
CHECK::No operator==(const Foo&, const Bar&), which would fool the check into thinking the operator was undefined.
- The
operator== in the CHECK namespace could shadow a globally defined operator== definition, resulting in a false negative.
Alternative Implementation
To fix the above issues and "simplify", one method is to use SFINAE. Although "simpler" is subjective here.
[edit] Link to working version: http://coliru.stacked-crooked.com/a/e9cc48729d53b6c6 , and updated code below
template <typename T, typename Arg = T>
class EqualExists {
template <class U = T, class V = Arg, bool Exists = !!sizeof(std::declval<U>() == std::declval<V>())>
static std::true_type Func(const T&, const Arg&);
template <class U, class V>
static std::false_type Func(const U&, const V&);
public:
static constexpr bool value = decltype(Func(std::declval<T>(), std::declval<Arg>()))::value;
};
[edit] My original answer had a bug : did not use template args U and V in the Exists computation, and did fail to compile on gcc. (worked on msvc for some reason)
template <class U, class V, bool Exists = !!sizeof(std::declval<T>() == std::declval<Arg>())>
static std::true_type Func(const T&, const Arg&);