const模板模板参数

时间:2018-03-01 14:50:44

标签: c++ c++11 templates eigen3 template-templates

我正在尝试设计以下(非常简化的)类:

template<int Dim, template<int,int> class Matrix>
class MatrixWrapperBase
{
    using InternalType Matrix<Dim,Dim>;
    InternalType member_;
public:
    // Provide additional functionalities
};

其中Matrix是实现公共矩阵功能的通用模板类;在我的具体情况下,它只是Eigen::Matrix类的typedef:

template<int R, int C>
using MyMatrix = Eigen::Matrix<double,R,C>;

现在,我想使用以下别名提供此类的非constconst InternalType版本(受迭代器启发):

template<int Dim>
using MatrixWrapper = MatrixWrapperBase<Dim,MyMatrix>;

template<int Dim>
using ConstMatrixWrapper = MatrixWrapperBase<Dim,const MyMatrix>;   // ERROR

我完全清楚后者不能编译的原因(在这个答案中很好地解释了它们,例如template template class with const template parameter),所以我试图为{{使用另一个模板模板参数别名1}}案例:

const

不幸的是,当我尝试实例template<int R, int C> using MyConstMatrix = Eigen::Matrix<const double, R, C>; ... template<int Dim> using ConstMatrixWrapper = MatrixWrapperBase<Dim,MyConstMatrix>; 对象(或ConstMatrixWrapper对象)时,Eigen拒绝编译,因为以下错误:

MyConstMatrix

我通过向/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:474:27: error: ‘static Eigen::PlainObjectBase<Derived>::MapType Eigen::PlainObjectBase<Derived>::Map(Eigen::PlainObjectBase<Derived>::Scalar*) [with Derived = Eigen::Matrix<const double, 2, 2>; Eigen::PlainObjectBase<Derived>::MapType = Eigen::Map<Eigen::Matrix<const double, 2, 2>, 0, Eigen::Stride<0, 0> >; Eigen::PlainObjectBase<Derived>::Scalar = const double]’ cannot be overloaded static inline MapType Map(Scalar* data) ^ /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:472:32: error: with ‘static Eigen::PlainObjectBase<Derived>::ConstMapType Eigen::PlainObjectBase<Derived>::Map(const Scalar*) [with Derived = Eigen::Matrix<const double, 2, 2>; Eigen::PlainObjectBase<Derived>::ConstMapType = const Eigen::Map<const Eigen::Matrix<const double, 2, 2>, 0, Eigen::Stride<0, 0> >; Eigen::PlainObjectBase<Derived>::Scalar = const double]’ static inline ConstMapType Map(const Scalar* data) 类添加bool模板参数找到了一种解决方法,以这种方式区分MatrixWrapperBase和非const案例:< / p>

const

但如果可能的话,我想避免这样的设计。

任何人都可以给我一个提示吗?提前谢谢。

2 个答案:

答案 0 :(得分:0)

我建议:

template <typename M> struct MatrixWrapperHelper;

template<int D1, int D2, template<int,int> class Matrix>
struct MatrixWrapperHelper<Matrix<Dim1, Dim2>>
{
    template <int NewDim1, int NewDim2>
    using ResizedType = Matrix<NewDim1, NewDim2>;

    static constexpr int Dim1 = D1;
    static constexpr int Dim2 = D2;
};


template <typename M> class MatrixWrapperBase
{
    using MatrxType = std::decay_t<M>;
    // MatrixWrapperHelper<MatrxType>::Dim1
    // typename MatrixWrapperHelper<MatrxType>::template Resized<42, 42>

    using InternalType = M;
    M member_;
public:
    // Provide additional functionalities
};

最后:

template<int Dim>
using MatrixWrapper = MatrixWrapperBase<MyMatrix<Dim, Dim>>;

template<int Dim>
using ConstMatrixWrapper = MatrixWrapperBase<const MyMatrix<Dim, Dim>>;

答案 1 :(得分:0)

  

我找到了一个解决方法,通过向MatrixWrapperBase类添加一个bool模板参数来以这种方式区分const和非const的情况[...]但是如果可能的话我想避免这样的设计。

其他bool模板参数出了什么问题?

无论如何,您可以使用部分模板专精化默认bool模板值来获取类似内容。

以下是完整的编译示例

#include <type_traits>

template <int, int>
struct Mtx
 { };

template <typename T, bool = false, bool = std::is_const<T>::value>
struct MatrixWrapperBase 
 { };

template <int Dim, template <int,int> class Matrix, bool C>
struct MatrixWrapperBase<Matrix<Dim, Dim>, C, false>
 {
   using InternalType = typename std::conditional<C,
            Matrix<Dim, Dim> const, Matrix<Dim, Dim>>::type;
 };

template <typename T>
struct MatrixWrapperBase<T, false, true>
   : public MatrixWrapperBase<typename std::remove_const<T>::type,
                              true, false>
 { };

int main()
 {
   MatrixWrapperBase<Mtx<1, 1>>        mwb;
   MatrixWrapperBase<Mtx<1, 1> const>  cmwb;

   static_assert( std::is_same<typename decltype(mwb)::InternalType,
                               Mtx<1, 1>>{}, "!");
   static_assert( std::is_same<typename decltype(cmwb)::InternalType,
                               Mtx<1, 1> const> {}, "!");

 }