Dukales

non-type template parameters

Nov 12th, 2015
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.11 KB | None | 0 0
  1. #include <utility>
  2.  
  3. // main.cpp
  4. #include <type_traits>
  5.  
  6. #include <cstdlib>
  7. #include <cassert>
  8.  
  9. namespace
  10. {
  11.    
  12. template< typename type >
  13. constexpr std::decay_t< type > any = std::decay_t< type >{};
  14.  
  15. static_assert(!any< volatile bool const & >); // is definitely constexpr
  16.  
  17. // try to construct from or bind (for references) to ...
  18. #if 1
  19. // ... variable template
  20. template< typename type, type cvrefvalue = std::forward< type >(any< type >) >
  21. // even for value:
  22. // main.cpp:20:44: error: non-type template argument is not a constant expression
  23. // template< typename type, type cvrefvalue = any< type > >
  24. //                                            ^
  25. #elif 0
  26. // ... free constexpr variable
  27. constexpr bool b = false;
  28. template< typename type, type cvrefvalue = b >
  29. // ok for (cv-ref-qualified) values, but for (cv-qualified) references:
  30. // main.cpp:27:44: error: value of type 'const bool' is not implicitly convertible to 'bool &'
  31. // template< typename type, type cvrefvalue = b >
  32. //                                            ^
  33. #elif 0
  34. // try to bind to non-type template parameter
  35. template< typename type, std::decay_t< type > value = std::decay_t< type >{}, type cvrefvalue = value >
  36. #elif 0
  37. template< typename type, type cvrefvalue{} >
  38. #elif 0
  39. template< typename type, type cvrefvalue = {} >
  40. #else
  41. template< typename type, type cvrefvalue = std::decay_t< type >{} >
  42. #endif
  43. struct test
  44. {
  45.     static_assert(std::is_rvalue_reference< type >{} == std::is_rvalue_reference< decltype(cvrefvalue) >{});
  46.     static_assert(std::is_lvalue_reference< type >{} == std::is_lvalue_reference< decltype(cvrefvalue) >{});
  47.     using lhs = std::remove_reference_t< type >;
  48.     using rhs = std::remove_reference_t< decltype(cvrefvalue) >;
  49.     //static_assert(std::is_const< lhs >{} == std::is_const< rhs >{}); // not true for cv-qualified `type`
  50.     //static_assert(std::is_volatile< lhs >{} == std::is_volatile< rhs >{}); // not true for cv-qualified `type`
  51.     static_assert(!std::is_const< rhs >{});
  52.     static_assert(!std::is_volatile< rhs >{});
  53. };
  54.  
  55. }
  56.  
  57. int
  58. main()
  59. {
  60. #if 0
  61.     using T = struct {}; // a non-type template parameter cannot be class
  62. #elif 0
  63.     struct T {}; // a non-type template parameter cannot be class
  64. #else
  65.     using T = bool;
  66. #endif
  67.     static_assert(std::is_default_constructible< T >{}); // only the requirements
  68.    
  69.     // value
  70. #if 0
  71.     static_cast< void >(test< T >{});
  72. #endif
  73.     // v-qualified value
  74. #if 0
  75.     static_cast< void >(test< volatile T >{});
  76. #endif
  77.     // c(v)-qualified values
  78. #if 1
  79.     static_cast< void >(test< T const >{});
  80.     static_cast< void >(test< volatile T const >{});
  81. #endif
  82.     // references for (cv-qualified) values
  83. #if 0
  84.     static_cast< void >(test< T & >{});
  85.     static_cast< void >(test< T const & >{});
  86.     static_cast< void >(test< volatile T & >{});
  87.     static_cast< void >(test< volatile T const & >{});
  88.    
  89.     static_cast< void >(test< T && >{});
  90.     static_cast< void >(test< T const && >{});
  91.     static_cast< void >(test< volatile T && >{});
  92.     static_cast< void >(test< volatile T const && >{});
  93. #endif
  94.     return EXIT_SUCCESS;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment