isvalid2.cpp

The following code example is taken from the book
C++ Templates - The Complete Guide, 2nd Edition
by David Vandevoorde, Nicolai M. Josuttis, and Douglas Gregor,
Addison-Wesley, 2017
© Copyright David Vandevoorde, Nicolai M. Josuttis, Douglas Gregor 2017


#include "isvalid.hpp"
#include<iostream>
#include<string>
#include<utility>

constexpr auto hasFirst
  = isValid([](auto&& x) -> decltype((void)&x.first) {
            });
template<typename T>
using HasFirstT = decltype(hasFirst(std::declval<T>()));

constexpr auto hasSizeType
  = isValid([](auto&& x)
             -> typename std::decay_t<decltype(x)>::size_type {
            });
template<typename T>
using HasSizeTypeT = decltype(hasSizeType(std::declval<T>()));

constexpr auto hasLess
  = isValid([](auto&& x, auto&& y) -> decltype(x < y) {
            });
template<typename T1, typename T2>
using HasLessT = decltype(hasLess(std::declval<T1>(), std::declval<T2>()));

int main()
{
  using namespace std;

  cout << "first: " << HasFirstT<pair<int,int>>::value << '\n'; // true

  struct CX {
    using size_type = std::size_t;
  };
  cout << "size_type: " << HasSizeTypeT<CX>::value << '\n';     // true
  cout << "size_type: " << HasSizeTypeT<int>::value << '\n';    // false

  cout << HasLessT<int, char>::value << '\n';                   // true
  cout << HasLessT<string, string>::value << '\n';              // true
  cout << HasLessT<string, int>::value << '\n';                 // false
  cout << HasLessT<string, char*>::value << '\n';               // true
}