我喜欢Eigen的逗号初始化语法,但我更喜欢它类似于初始化列表初始化。
我试图自己实现这样的事情,但我遇到了一些我无法解决的问题。
我的方法如下:
#include <iostream>
#include <Eigen/Dense>
template <int Rows= Eigen::Dynamic, int Cols= Rows>
class MyMatrix: public Eigen::Matrix<double,Rows,Cols>
{
private:
using Matrix= Eigen::Matrix<double,Rows,Cols>;
public:
MyMatrix(): Matrix() {
std::cout << "MyMatrix()\n";
if /* constexpr */ (Rows!=Eigen::Dynamic) Matrix::setZero(); }
template <typename Derived>
MyMatrix(const Eigen::MatrixBase<Derived> &Other): Matrix(Other) // (2)
{ std::cout << "MyMatrix(const MatrixBase<Derived> &Other)\n"; }
template <typename TFirst,typename... TRest/*,typename= enable_if_t<NoIdea::value>*/>
MyMatrix(TFirst &&First,TRest &&... Rest) { *this << First, (Rest, ...); }
};
int main()
{
MyMatrix<3> Mat1= MyMatrix<3>::Identity();
MyMatrix<3> Mat2= { MyMatrix<3>::Identity() };
MyMatrix<3> Mat3= { 1.0, 0.0, 0.0, // Runtime error
0.0, 1.0, 0.0,
0.0, 0.0, 1.0 };
MyMatrix<3> Mat4= MyMatrix<3>::Identity()+MyMatrix<3>::Ones();
MyMatrix<3> Mat5= {};
}
这段代码用g ++ - 6编译,但它有(至少)两个问题:
MyMatrix
实例实际上使用初始化列表(qazxsw poi)。似乎折叠表达式不能像我想的那样工作。任何帮助将非常感激。
我刚刚意识到fold表达式中的错误。它应该是:
Too few coefficients passed to comma initializer (operator<<)
编辑:由于我对使用单个元素的init-lists不感兴趣,以下解决方案避免了构造函数歧义问题:
(*this << First),...,Rest;
不幸的是,这段代码不能用g ++ - 6编译(可能是因为template <typename TFirst,typename TSecond,typename... TRest>
MyMatrix(TFirst &&First,TSecond &&Second,TRest &&... Rest)
{ ((*this << First, Second), ... , Rest); }
),但它与clang ++ - 3.8一起编译。
现在我可以写:
bug 68377
代替:
MyMatrix<3> m= { MyMatrix<2,2>::Ones(), MyMatrix<2,1>::Zero(),
MyMatrix<1,2>::Zero(), 0.0 };
这是我提出的解决方案:
MyMatrix<3> m= ( MyMatrix<3>() << MyMatrix<2,2>::Ones(), MyMatrix<2,1>::Zero(),
MyMatrix<1,2>::Zero(), 0.0 ).finished();
其中// very dark magic
template<int M, int N=M>
constexpr auto MakeMatrix = [](auto m, auto... ms) {
return ((Matrix<M,N>()<<m),...,ms).finished();
};
是:
Matrix<M,N>
用法如下:
template<int M, int N=M>
using Matrix = Eigen::Matrix<double, M, N>;
(输出)
auto v = Matrix<2,1>::Zero();
auto m = Matrix<2>::Identity();
std::cout<< MakeMatrix<2,3>(v,m);