Let’s dissect the above method and see what’s happening.

has_helper method has two possible overload options. For the int
datatype both are possible overload candidates but as we saw earlier
compiler prefers the non-variadic option. So it choosses the first
option which has a return type of std::true_type.

However for complex<int>, compiler has only one option since <
doesn’t exist for complex type.

// we don't need to define the methods
// Since we are not calling them.
// we are just using the principle of SFINAE that applies to template
// arguments and not to the body
template<typenameT,typenameunused=decltype(T()<T())>std::true_typehas_less_helper(constT&);//and
template<typenameT>std::false_typehas_less_helper(...);

We could directly use has_less_helper to know what Type has a less
than operator defined for it. However it is important to note that the
has_less_helper assumes that type T has a default constructor
defined for it(decltype(T() < T())).

To remove above dependency we could use declvalue(as discussed in
previous post). That is what we are
doing in has_less method.

template<typenameT>constexprboolhas_less(void){// using is equivalent to typedef
usingmy_type=decltype(has_less_helper<T>(std::declval<T>()));// note that the return type is either true_type or false_type
returnmy_type::value;}

Note: the constexpr keyword makes the method evaluate at compile time. So we will have a true or false value from this method at compile time.

Inside our definition of generic BinarySearchTree we put a
static_assert(compile time assert) to check that we have a less that
operator define for the type T.

template<typenameT>classBinarySearchTree{public:static_assert(has_less<T>(),"Assertion failed. No less than operation defined.");BinarySearchTree(){}};

That’s it! Now when you declare something like

BinarySearchTree<complex<int>>compBinarySearchTree;

We get a compile time error.

Awesome! Now you understand the concept of concept checking. Happy
coding.