I am currently working on a small math vector class. I want two class vectors, Vector2
and Vector3
be constructive from one to the other. For example:
Vector2<float> vec2(18.5f, 32.1f);
Vector3<float> vec3(vec2);
To do this and facilitate extensibility, I would like to use features VectorTraits
with its basic definition:
template <typename T>
struct VectorTraits
{
typedef T VectorType;
typedef typename T::ValueType ValueType;
static const unsigned int dimension = T::dimension;
};
This form will allow the user to establish a relationship between existing Vector classes (e.g. glm :: vec2, for example) and my classes. Then it would be possible to create Vector2 from glm :: vec2.
In addition, this method allowed me to write a generic streaming operator for all classes defining VectorTraits
using SFINAE.
, operator<<
, , VectorTraits
.
( ):
#include <iostream>
#include <type_traits>
struct Dummy
{};
template <typename T>
struct VectorTraits
{
typedef T VectorType;
typedef typename T::ValueType ValueType;
static const std::uint16_t dimension = T::dimension;
};
struct Vec
{
typedef float ValueType;
static const std::uint16_t dimension = 2;
};
std::ostream& operator<<(std::ostream& stream, const Dummy& d)
{
stream << "dummy.\n";
return stream;
}
template <class T, std::enable_if_t<(VectorTraits<T>::dimension > 0)>>
std::ostream& operator<<(std::ostream& stream, const T& vec)
{
std::cout << "Traits. Dimension = " << VectorTraits<T>::dimension << "\n";
}
int main()
{
std::cout << "Test\n";
std::cout << Vec();
std::cout << Dummy();
return 0;
}
error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Vec')
prog.cpp:33:15: note: candidate: template<class T, typename std::enable_if<(VectorTraits<T>::dimension > 0), void>::type <anonymous> > std::ostream& operator<<(std::ostream&, const T&)
std::ostream& operator<<(std::ostream& stream, const T& vec)
^
prog.cpp:33:15: note: template argument deduction/substitution failed:
prog.cpp:41:19: note: couldn't deduce template parameter '<anonymous>'
template <class T, std::enable_if_t<(VectorTraits<T>::dimension > 0)>>
template <class T, std::enable_if_t<(VectorTraits<T>::dimension > 0)>* = 0>
prog.cpp:13:35: error: 'char [21]' is not a class, struct, or union type
typedef typename T::ValueType ValueType;
, , VectorTraits
, Vector
. "" Vector
typedef
.
, - . , , .