#include <iostream>
    #include <type_traits>

    // Traits class
    template <typename T, typename = void>
    struct VectorTraits;
    
    template <typename T>
    struct VectorTraits<T, std::enable_if_t<(T::dimension > 0)>>
    {
      typedef T                       VectorType;
      typedef typename T::ValueType   ValueType;
      static const std::uint16_t      dimension = T::dimension;
    };
    
    
    // Fake vector class. Defines the required typedef.
    struct Vec
    {
      typedef float   ValueType;
      static const std::uint16_t dimension = 2;
    };
    
    // Fake vector class. Defines the required typedef.
    struct VecFake
    {
    };
    
    template <>
    struct VectorTraits<VecFake>
    {
      typedef VecFake                       VectorType;
      typedef float   ValueType;
      static const std::uint16_t      dimension = 12;
    };
    
    // Streaming operator attempt for classes defining VectorTraits.
    template <class T, typename = std::enable_if_t<(sizeof(VectorTraits<T>) > 0)>>
    std::ostream& operator << (std::ostream& stream, const T& )
    {
        return stream << "Traits. Dimension = " << VectorTraits<T>::dimension << "\n";
    }
    
    int main()
    {
        std::cout << "Test\n";
        std::cout << Vec();
        std::cout << VecFake();
    }