我正在尝试设计以下(非常简化的)类:
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>;
现在,我想使用以下别名提供此类的非const
和const 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
但如果可能的话,我想避免这样的设计。
任何人都可以给我一个提示吗?提前谢谢。
答案 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> {}, "!");
}