我正在出于教育目的查看 Eigen 源代码。我注意到对于每个具体的类模板X
在层次结构中,有一个internal::traits<X>
定义的。一个典型的例子可以在 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
};
};
}
现在,我将特征理解为扩展现有类的一种方式,您不想使用与某些新代码相关的额外信息来修改这些类。例如,类模板的用户Foo<class TAllocator>
可能想利用现有的内存分配器FastAlloc
and AlignedAlloc
,但是 Foo 需要知道如何与这两者交互,因此FooTraits<AlignedAlloc>::allocate()
and FooTraits<FastAlloc>::allocate()
由用户定义,然后由用户使用Foo
.
然而,在这种情况下,我并不能轻易地看到仅指定的问题Scalar
在每个派生类中,即有Matrix
define Matrix::Scalar
在类主体中使用 typedef。使用特征类有什么好处?是否只是为了保持代码整洁,即将每个类的所有相关属性存储在特征类中?
根据 Nicol Bolas 的回复进行编辑:我知道其中一些 typedef 可能需要保留为“内部”,即不应暴露给用户,这将解释特征类。这似乎是有道理的,但是其中一些 typedef,例如Scalar
, are通过基类中的 typedef 可供外界使用Matrix
:
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;
这让我们回到了最初的问题:为什么不呢?Scalar
只是一个 typedefMatrix
本身?除了风格选择之外还有什么原因吗?