我正在尝试编写一个只接受通过const
引用传递的左值特征表达式的函数。我的第一个想法是只保留重载const Eigen::MatrixBase<Derived>&
和delete
Eigen::MatrixBase<Derived>&&
。令我惊讶的是,delete
d函数不是重载候选集的一部分。所以我尝试了下面的代码
#include <iostream>
#include <Eigen/Dense>
#define PRINT_MY_NAME std::cout << __PRETTY_FUNCTION__ << '\n'
template<typename Derived>
void f(const Eigen::MatrixBase<Derived>&) // (1)
{
PRINT_MY_NAME;
}
template<typename Derived>
void f(Eigen::MatrixBase<Derived>&&) // (2)
{
PRINT_MY_NAME;
}
int main()
{
Eigen::MatrixXd A;
f(A); // invokes (1)
f(A + A); // invokes also (1) !!!
}
输出(gcc5.2)
void f(const Eigen :: MatrixBase&amp;)[with Derived = Eigen :: Matrix&lt; double,-1,-1&gt;]
void f(const Eigen :: MatrixBase&amp;)[with Derived = Eigen :: CwiseBinaryOp&lt; Eigen :: internal :: scalar_sum_op&lt; double&gt;,const Eigen :: Matrix&lt; double,-1,-1&gt;,const Eigen :: Matrix&lt; double,-1,-1&gt; &GT;]
很明显,不考虑右值超载。现在很清楚,第二个不是更好的匹配,因为我传递了一个rvalue Eigen表达式,它可以转换为Eigen::MatrixBase<>
,但不是完全相同的类型。现在我的问题出现了:
f
参数传递的右值特征表达式?问题是表达式可以具有任意类型(Eigen使用表达式模板),如CwiseBinaryOp<...CwiseBinaryOp<...>>
等。这是一个更大问题的一部分,我有一个类似于实用程序的函数,它接受一个左值并将它绑定到类中的const
引用表达式。如果表达式是一个rvalue,那么所有的赌注都是关闭的,因为引用绑定不是通过构造函数参数传播的,所以我想禁止传递rvalue Eigen表达式。答案 0 :(得分:2)
我想我发现了正在发生的事情:表达式模板A + A
的结果是const
,因此存在CV不匹配。将const
添加到第二个重载会:
template<typename Derived>
void f(const Eigen::MatrixBase<Derived>&&) // (2)
{
PRINT_MY_NAME;
}