fork download
  1. #include <type_traits>
  2. #include <string>
  3.  
  4.  
  5. std::string fooImpl(int i) { return "int!"; }
  6.  
  7. template <class T>
  8. struct HasFooImpl_ {
  9. template <typename C>
  10. static std::true_type test(decltype(fooImpl(std::declval<C>()))*);
  11. template <typename C>
  12. static std::false_type test(...);
  13. typedef decltype(test<T>(0)) type;
  14. };
  15.  
  16. template <typename T>
  17. using HasFooImpl = typename HasFooImpl_<T>::type;
  18.  
  19. template <typename T>
  20. typename std::enable_if<HasFooImpl<T>::value, std::string>::type
  21. foo(T&& t)
  22. {
  23. return fooImpl(std::forward<T>(t));
  24. }
  25.  
  26. template <typename T>
  27. typename std::enable_if<!HasFooImpl<T>::value, std::string>::type
  28. foo(T&& t)
  29. {
  30. return "generic!";
  31. }
  32.  
  33. struct X{};
  34.  
  35. template <class T>
  36. struct S{};
  37. template <class T>
  38. std::string fooImpl(S<T> const&) { return "S<T>"; }
  39.  
  40.  
  41. #include <iostream>
  42. int main()
  43. {
  44. std::cout << foo(1) << '\n';
  45. std::cout << foo("nope") << '\n';
  46. std::cout << foo(S<unsigned>{}) << '\n';
  47. std::cout << foo(X{}) << '\n';
  48. std::cout << foo(3.4) << '\n'; //will call fooImpl(int)
  49. }
Success #stdin #stdout 0s 3028KB
stdin
Standard input is empty
stdout
int!
generic!
S<T>
generic!
int!