【发布时间】:2019-07-21 07:54:52
【问题描述】:
我真的无法总结问题中的问题。我已经提出了类似的问题here。在那里我请求帮助定义static constexpr 矩阵。解决方案是在模板矩阵列表中添加另一个参数,基本上是Matrix<T,Rows,Cols,std::make_index_sequence<Rows*Cols>>。
我接受了答案,但后来我注意到在这个版本中,我的旧代码无法支持以Matrix<T,Rows,Cols> 为参数的函数的调用,例如:
foo(Matrix<T,Rows,Cols> & foo){...}
由于缺少第四个隐式参数给我一个编译错误,即candidate template ignored: could not match '__make_integer_seq' against 'integer_sequence'。
- 请有人向我解释一下为什么以及我应该怎么做才能解决 这?我想它是可以修复的,但我无法弄清楚。
然后我发现我可以用不同的方式定义类,保持经典结构Matrix<T,Rows,Cols>,但仍然可以定义static constexpr矩阵(我只是在这里添加了必要的):
template<typename T, Integer Rows_, Integer Cols_>
class Matrix {
public:
static constexpr Integer Rows=Rows_;
static constexpr Integer Cols=Cols_;
using type= Matrix<T,Rows,Cols>;
using subtype=T;
~Matrix()=default;
Matrix() {}
template<typename...Inputs>
constexpr Matrix (const Inputs&...vals)
: values{{ {static_cast<T>(vals)}...}}
{static_assert(sizeof...(Inputs)==Rows*Cols, "...");}
private:
std::array<T, Rows * Cols> values;
};
因此,使用构造函数中的static_cast(),我可以在不更改 Matrix 类的模板的情况下定义静态矩阵。我可以做一些事情
static constexpr Matrix< double, 2, 2> A{1.,2.,3.,4.};
但我也可以保持对foo(Matrix<T,Rows,Cols> & foo){...} 等函数的调用。所以我对这个解决方案很满意。但是后来我尝试创建一个矩阵矩阵,我发现这个类版本在这种构造函数中失败了:
Matrix< Matrix<double,1,1>, 2, 2> A{{0.1},{0.1},{0.1},{0.1}};
即使我先初始化元素然后将它们作为参数传递它会成功:
static constexpr Matrix< double, 1,1> a{{0.1}};
static constexpr Matrix< Matrix<double,1,1>, 2, 2> A{a,a,a,a};
但是,如果可能的话,我想避免这种情况。
作为一个更清楚的例子,我将给出这个:
Matrix< Matrix<Real,1,1>, 2, 2> A{a,a,a,{0.1}};
这会产生以下编译错误:
candidate template ignored: substitution failure : deduced incomplete pack <Matrix<double, 1, 1>, Matrix<double, 1, 1>, Matrix<double, 1, 1>,
(no value)> for template parameter 'Inputs'``` (so ```{0.1}``` is no value).
如果我写的是构造函数Matrix<double,1,1>{0.1}而不是{0.1},那么它可以工作,但是看起来很可怕。
- 为什么我不能简单地构造矩阵的元素
{0.1}的系列?有什么解决方法吗?
【问题讨论】:
标签: c++ c++14 variadic-templates template-specialization template-argument-deduction