I am looking at Eigen source code for educational purposes. I noticed that for every particular class X template in the hierarchy, there is internal::traits<X> . A typical example can be found in Matrix.h:
namespace internal { template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > { typedef _Scalar Scalar; typedef Dense StorageKind; typedef DenseIndex Index; typedef MatrixXpr XprKind; enum { RowsAtCompileTime = _Rows, ColsAtCompileTime = _Cols, MaxRowsAtCompileTime = _MaxRows, MaxColsAtCompileTime = _MaxCols, Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret, CoeffReadCost = NumTraits<Scalar>::ReadCost, Options = _Options, InnerStrideAtCompileTime = 1, OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime }; }; }
Now I understand the features as a way to extend existing classes that you don't want to modify, with additional information related to some piece of new code. For example, a user of the class template Foo<class TAllocator> might want to use existing FastAlloc and AlignedAlloc memory FastAlloc , but Foo needs to know how to interact with the two, and as such FooTraits<AlignedAlloc>::allocate() and FooTraits<FastAlloc>::allocate() defined by the user, which in turn is used by Foo .
However, in this case, I do not see a problem with just specifying Scalar in each derived class, i.e. has a Matrix define Matrix::Scalar using typedef in the body of the class. What is the advantage of using a feature class? This is just to keep the code clean, i.e. Save all the relevant properties of each class in a feature class?
Edit according to Nicol Bolas answer: I understand that some of these typedefs may need to be kept "internal", that is, they should not be exposed to the user, which explains the feature class. This makes sense, however, some of these typedefs, such as Scalar , are available to the outside world through a typedef in the base Matrix class:
template<typename Derived> class MatrixBase : public DenseBase<Derived> { public: typedef MatrixBase StorageBaseType; typedef typename internal::traits<Derived>::StorageKind StorageKind; typedef typename internal::traits<Derived>::Index Index; typedef typename internal::traits<Derived>::Scalar Scalar; typedef typename internal::packet_traits<Scalar>::type PacketScalar; typedef typename NumTraits<Scalar>::Real RealScalar;
This brings us back to the original question: why isn't Scalar just a typedef in Matrix itself? Is there any reason besides the stylistic choice?