将特征类型作为参数的函数的返回类型不清楚

时间:2017-07-28 11:34:01

标签: c++ templates eigen eigen3

我正在尝试在科学计划中使用Eigen3库,但我正在努力制作一些简单的函数和成员函数。例如,我不确定我应该选择什么类型的返回类型,如下所示:

template <typename DerivedA,typename DerivedB>
inline **something** mult(const MatrixBase<DerivedA>& p1,
                          const MatrixBase<DerivedB>& p2)
  {
  return p1*p2;
  }

我假设有一些类,比如productOp,我可以毫无问题地返回。我仍然无法想象在涉及大量操作的函数中会发生什么,甚至更糟糕的是,依赖于输入的迭代:

template <typename Derived>
**something** foo(const MatrixBase<Derived>& p1))
  {
  **something** p2;
  p2.setZero();
  while(p2(0,0) < 1)
    p2 += p1; 
  return p2;
  }

我的问题是:

  1. 第二个例子是否可能?
  2. 如何计算p1*p2等操作的类型?
  3. 在精心设计的功能的情况下如何计算返回类型?

3 个答案:

答案 0 :(得分:3)

在第一个示例中,返回auto将很有效,因为它是一个不引用任何本地临时表达式的单个表达式。

在第二种情况下,您需要创建并返回具有自己存储的实际矩阵/向量,例如:

typename Derived::PlainObject p2;
p2.resizeLike(p1);

,返回类型为typename Derived::PlainObject

答案 1 :(得分:1)

如果文档不喜欢返回类型的auto,那么你可以做的一件事是使用尾随返回类型并获取它们DerivedA * DerivedB的类型。那看起来像是

inline auto mult(...) -> MatrixBase<decltype(std::declval<DerivedA>() * std::decval<DerivedB>())>

答案 2 :(得分:1)

这是第一个表达式的手动解决方案,如果您不想使用C ++ 11,或者您希望确保实际评估表达式:

template<class DerivedA, class DerivedB>
Eigen::Matrix<typename Eigen::ScalarBinaryOpTraits<typename DerivedA::Scalar, typename DerivedB::Scalar>::ReturnType, 
              DerivedA::RowsAtCompileTime, DerivedB::ColsAtCompileTime>
mult(const Eigen::MatrixBase<DerivedA>& p1, const Eigen::MatrixBase<DerivedB>& p2)
{
    return p1*p2;
}

ScalarBinarayOpTraits用于确定是否可以组合两种不同的标量类型(例如doublestd::complex<double>)。

使用示例:

Eigen::Matrix3Xcd M1 = mult(Eigen::Matrix3d(), Eigen::Matrix3Xcd(3,20));

如果将临时对象传递给mult并将结果存储在auto变量中,这也更安全,例如:

double *someData = ...;
Eigen::MatrixXd someMatrix = ...; 
auto result = mult(Eigen::Matrix3d::Map(someData), someMatrix.topLeftCorner<3,4>());

对于第二个例子,正如ggael写的typename Derived::PlainObject就足够了。你可以使用p2.setZero(p1.rows(), p2.cols()); to initialize p2`;