fork download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. namespace tmpl
  5. {
  6.  
  7. namespace detail
  8. {
  9.  
  10. template<template<typename...> class C, typename... T>
  11. struct is_valid_instantiation_impl
  12. {
  13. // Default constructor
  14. template<template<typename...> class D>
  15. static std::true_type test(decltype(D<T...>{ })*, int);
  16. // Copy constructor
  17. template<template<typename...> class D>
  18. static std::true_type test(decltype(D<T...>{ std::declval<const D<T...>&>() })*, long);
  19. // Move constructor
  20. template<template<typename...> class D>
  21. static std::true_type test(decltype(D<T...>{ std::declval<D<T...>&&>() })*, int*);
  22.  
  23. template<template<typename...> class D>
  24. static std::false_type test(...);
  25.  
  26. using type = decltype(test<C>(nullptr, 0));
  27. // ^ this one
  28. };
  29.  
  30. } // namespace detail
  31.  
  32. template<template<typename...> class C, typename... T>
  33. struct is_valid_instantiation : detail::is_valid_instantiation_impl<C, T...>::type { };
  34.  
  35. } // namespace tmpl
  36.  
  37. template<typename>
  38. struct tester
  39. {
  40. tester(const tester&) = delete;
  41. tester(tester&&) = delete;
  42.  
  43. private:
  44. tester();
  45. };
  46.  
  47. template<>
  48. struct tester<char>;
  49.  
  50. template<>
  51. struct tester<int>
  52. {
  53. tester(int);
  54. };
  55.  
  56. int main(int argc, char** argv)
  57. {
  58. std::cout << "instantiable<char>: " << tmpl::is_valid_instantiation<tester, char>::value << std::endl;
  59. std::cout << "instantiable<int>: " << tmpl::is_valid_instantiation<tester, int>::value << std::endl;
  60. std::cout << "instantiable<float>: " << tmpl::is_valid_instantiation<tester, float>::value << std::endl;
  61. }
  62.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In instantiation of 'struct tmpl::detail::is_valid_instantiation_impl<tester, int>':
prog.cpp:33:8:   required from 'struct tmpl::is_valid_instantiation<tester, int>'
prog.cpp:59:82:   required from here
prog.cpp:26:30: error: call of overloaded 'test(std::nullptr_t, int)' is ambiguous
   using type =  decltype(test<C>(nullptr, 0));
                              ^
prog.cpp:26:30: note: candidates are:
prog.cpp:18:25: note: static std::true_type tmpl::detail::is_valid_instantiation_impl<C, T>::test(decltype (D<T ...>{declval<const D<T ...>&>()})*, long int) [with D = tester; C = tester; T = {int}; std::true_type = std::integral_constant<bool, true>; decltype (D<T ...>{declval<const D<T ...>&>()}) = tester<int>]
   static std::true_type test(decltype(D<T...>{ std::declval<const D<T...>&>() })*, long);
                         ^
prog.cpp:21:25: note: static std::true_type tmpl::detail::is_valid_instantiation_impl<C, T>::test(decltype (D<T ...>{declval<D<T ...>&&>()})*, int*) [with D = tester; C = tester; T = {int}; std::true_type = std::integral_constant<bool, true>; decltype (D<T ...>{declval<D<T ...>&&>()}) = tester<int>]
   static std::true_type test(decltype(D<T...>{ std::declval<D<T...>&&>() })*, int*);
                         ^
prog.cpp:24:26: note: static std::false_type tmpl::detail::is_valid_instantiation_impl<C, T>::test(...) [with D = tester; C = tester; T = {int}; std::false_type = std::integral_constant<bool, false>]
   static std::false_type test(...);
                          ^
prog.cpp: In function 'int main(int, char**)':
prog.cpp:59:41: error: 'value' is not a member of 'tmpl::is_valid_instantiation<tester, int>'
   std::cout << "instantiable<int>: " << tmpl::is_valid_instantiation<tester, int>::value << std::endl;
                                         ^
stdout
Standard output is empty