fork download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. // To define another operator
  5. struct Dummy
  6. {};
  7.  
  8. // Traits class
  9. template <typename T, typename = void>
  10. struct VectorTraits_impl
  11. {
  12. };
  13.  
  14.  
  15. template <typename T>
  16. struct VectorTraits_impl<T, std::enable_if_t<std::is_integral<decltype(T::dimension)>::value>>
  17. {
  18. typedef T VectorType;
  19. typedef typename T::ValueType ValueType;
  20. static const std::uint16_t dimension = T::dimension;
  21. };
  22.  
  23. // Traits class
  24. template <typename T>
  25. using VectorTraits = VectorTraits_impl<T>;
  26.  
  27. // Fake vector class. Defines the required typedef.
  28. struct Vec
  29. {
  30. typedef float ValueType;
  31. static const std::uint16_t dimension = 2;
  32. };
  33.  
  34. // Fake vector class. Defines the required typedef.
  35. struct VecFake
  36. {
  37. };
  38.  
  39. template <>
  40. struct VectorTraits_impl<VecFake>
  41. {
  42. typedef VecFake VectorType;
  43. typedef float ValueType;
  44. static const std::uint16_t dimension = 12;
  45. };
  46.  
  47. // Streaming operator for Dummy.
  48. std::ostream& operator<<(std::ostream& stream, const Dummy&)
  49. {
  50. stream << "dummy.\n";
  51. return stream;
  52. }
  53.  
  54. // Streaming operator attempt for classes defining VectorTraits.
  55. template <class T, typename = std::enable_if_t<(VectorTraits<T>::dimension > 0)>>
  56. std::ostream& operator << (std::ostream& stream, const T& )
  57. {
  58. return stream << "Traits. Dimension = " << VectorTraits<T>::dimension << "\n";
  59. }
  60.  
  61. int main()
  62. {
  63. std::cout << "Test\n";
  64. std::cout << Vec();
  65. std::cout << VecFake();
  66. std::cout << Dummy();
  67. }
Success #stdin #stdout 0s 3456KB
stdin
Standard input is empty
stdout
Test
Traits. Dimension = 2
Traits. Dimension = 12
dummy.