禁用 Eigen 表达式到 const 引用的临时绑定

Disable temporary binding of Eigen expression to const references

我正在尝试编写一个仅接受通过 const 引用传递的左值特征表达式的函数。我的第一个想法是只保留重载 const Eigen::MatrixBase<Derived>&deleteEigen::MatrixBase<Derived>&& 一个。令我惊讶的是,deleted 函数不是重载候选集的一部分。所以我尝试了下面的代码

#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&) [with Derived = Eigen::Matrix < double, -1, -1>]

void f(const Eigen::MatrixBase&) [with Derived = Eigen::CwiseBinaryOp < Eigen::internal::scalar_sum_op < double>, const Eigen::Matrix < double, -1, -1>, const Eigen::Matrix < double, -1, -1> >]

很明显没有考虑右值重载。现在我很清楚第二个不是更好的匹配,因为我传递了一个右值特征表达式,它可以转换为 Eigen::MatrixBase<>,但不是完全相同的类型。现在我的问题来了:

我想我找到了原因:表达式模板 A + A 的结果是 const,因此存在 CV 不匹配。将 const 添加到第二个重载中:

template<typename Derived>
void f(const Eigen::MatrixBase<Derived>&&)      // (2)
{
    PRINT_MY_NAME;
}