c++ - 尝试为特征矩阵实现一种初始化列表语法

标签 c++ variadic-templates eigen c++17

我喜欢 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 进行编译,但它(至少)有两个问题:

  1. 构造函数 (2) 从未被调用,我不知道如何鼓励编译器为适当的对象选择它。
  2. 我得到 MyMatrix 的断言失败实际上使用初始化列表( Too few coefficients passed to comma initializer (operator<<) )的实例。折叠表达式似乎没有按照我的意愿工作。

任何帮助将不胜感激。

最佳答案

我刚刚意识到折叠表达式中的错误。它应该是:

(*this << First),...,Rest;

编辑:由于我对具有单个元素的初始化列表不感兴趣,因此以下解决方案避免了构造函数歧义问题:

template <typename TFirst,typename TSecond,typename... TRest>
MyMatrix(TFirst &&First,TSecond &&Second,TRest &&... Rest)
  { ((*this << First, Second), ... , Rest); }

不幸的是,这段代码不能用 g++-6 编译(可能是因为 bug 68377 ),但可以用 clang++-3.8 编译。

现在我可以写:

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();

关于c++ - 尝试为特征矩阵实现一种初始化列表语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40174039/

相关文章:

c++ - 菜单驱动逻辑错误导致死循环

c++ - 如何将 Eigen 矩阵和 vector 类型转换为 Apple 的 simd 类型以传递给 GPU?

c++ - 带有模板成员函数和 std::invocable 的 C++20 概念中的错误

c++ - 将 std::forward 与 auto&& 一起使用是正确的做法吗

c++ - 计算函数被调用的次数

c++ - C++ 中的 Monad 接口(interface)

c++ - 可变参数模板函数参数的编译错误

c++ - 编译器错误或非标准代码? - lambda 中的可变参数模板捕获

c++ - 可变参数模板和 std::array 意外行为

c++ - 从模板类创建对象时出错