2

我有一个关于模板类的 C++ 项目(库)(不同类型的矩阵,每种类型都有不同的容器,容器有不同的 value_type - 向量等相同)。

每个模板类都有模板成员,因为

DenseRectangularMatrix<std::vector<long double>> //type-container-value_type

必须能够(如果是 5x5)乘以

DenseSymmetricMatrix<std::array<float,15>> //(5x5) type-container-value_type

我的问题是实例化的编译。由于许多模板关系,很难实例化所有可能的情况,不仅用于测试/调试,还用于检查是否发生编译器错误。

对此有什么想法吗?

4

1 回答 1

1

解决此类问题的 C 方法可能是使用宏和脚本来简化所有可能性的生成。但是,我们使用 C++ 进行编码,所以让我们用模板替换宏。毕竟,这些都是基本类型的宏。

所以我的想法是将你的类型分解为更基本的类型,并使用模板来构造它们。

enum {
    RECTANGULAR,
    SYMMETRIC,
} DimKind;

enum {
    DENSE,
    PARSE
} Density;

enum {
    STD_ARRAY,
    STD_VECTOR
} ContainerType;

enum {
    FLOAT,
    DOUBLE
} CoordType;

template <CoordType CT>
struct coord_def {
};

struct coord_def<FLOAT>{
    typedef float type;
};

struct coord_def<DOUBLE> {
    typedef double type;
};


template <ContainerType Cont, CoordType Coord, int Dimension>
struct container_def {
};

template <CoordType Coord, int Dim>
struct container_def<STD_ARRAY, Coord, Dim> {
    typedef std::array<Coord,Dim> type;
    static const int dim = Dim;
    // add any other helper function needed to build the test case for that particular
    // container
};

template <CoordType Coord, int Dim>
struct container_def<STD_VECTOR, Coord, Dim> {
    typedef std::vector<Coord> type;
    static const int dim = Dim;
};

template <Density D, DimKind DK, ContainerType Cont, 
                  CoordType Coord, int XDim, int YDim>
struct TestMatrix {
};

// here specialize the above according to the parameters
// you may need to include helper function to build an instance using the template
// parameters (dimension comesto mind)

然后,您必须定义要测试的操作类型。它们当然可以归类为带分量的矩阵、带向量的矩阵、带矩阵的矩阵。

enum { 
    // matrix ops list
} MatrixOp;

template <MatrixOp Op, typename M1, typename M2, typename Ret>
Ret binary_op(M1 m1, M2 m2);

 // overload for specific functions

template <MatrixOp Op,
                  ContainerType Cont1, ContainerType Cont2
                   CoordType Coord1, CoordType Coord2,
                   int XDim1, int YDim1, int XDim2, int YDim2,
                   Denstity D1, Density D2,
                   DimKind K1, DimKind K2>
struct test_op {
    typedef TestMatrix<...>::type M1;
    typedef TestMatrix<...>::type M2;
    void test(M1 m1, M2 m2){
         binary_op<MatrixOp,M1,M2>(m1, m2);
     }
};

接下来,您的矩阵之间肯定存在代数关系,您可以将其编码为模板,并用于您的测试。

例如,DenseSymmetricMatrix模板的参数似乎指定了一个静态大小的容器类型,对于这样一个 *n 矩阵,数组的维度必须是 n * (n+1) / 2。DenseRectangularMatrix另一方面,它的维度似乎定义为运行。但是由于您具有上述维度的关系,您可以轻松地将两个测试用例编写为模板:一个构建两个维度匹配的矩阵,另一个构建维度不匹配的矩阵。

最后一步是所有可能性的产生。一个简单的脚本遍历所有枚举值应该有助于生成所有可能的测试。

我相信您也可以使用现有的单元测试框架(如 boost 框架)和这些模板来构建您的测试。

于 2013-03-08T05:19:22.610 回答