禁用特征表达式与const引用的临时绑定 [英] Disable temporary binding of Eigen expression to const references

查看:186
本文介绍了禁用特征表达式与const引用的临时绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个函数,只接受通过 const 引用传递的lvalue特征表达式。我的第一个想法是只保留重载 const Eigen :: MatrixBase< Derived>& delete c $ c> Eigen :: MatrixBase< Derived>&&&< / code> one。令我吃惊的是, delete d函数不是重载候选集合的一部分。所以我试过下面的代码

  #include< iostream> 
#include< Eigen / Dense>

#define PRINT_MY_NAME std :: cout<< __PRETTY_FUNCTION__<< '\\\
'

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) // invoked(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 ,但是不是完全相同的类型。现在我的问题:




  • 如何禁用或检测作为 f ?问题是表达式可以具有任意类型(Eigen使用表达式模板),例如 CwiseBinaryOp< ... CwiseBinaryOp< ...>> 等。这是一个更大的问题的一部分,我有一个实用的make样函数,它接受一个左值,并绑定到一个 const 引用表达式。如果表达式是一个右值,那么所有的注单都会关闭,因为引用绑定不是通过构造函数传递的,所以我想禁止传递右值特征表达式。


解决方案

我想我发现了发生了什么:表达式模板的结果 A + A const ,所以有一个CV不匹配。将 const 添加到第二个重载中:

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


I am trying to write a function that accepts only lvalue Eigen expressions passed via const references. My first idea was to keep only the overload const Eigen::MatrixBase<Derived>& and delete the Eigen::MatrixBase<Derived>&& one. To my surprise, the deleted function was not part of the overload candidate set. So I tried the code below

#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) !!!
}

which outputs (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> >]

so clearly the rvalue overload is not considered. It is now clear for me that the second one is not a better match, since I pass a rvalue Eigen expression, which is convertible to Eigen::MatrixBase<>, but is not the exact same type. Now comes my question:

  • How can I disable or detect rvalue Eigen expressions passed as parameters for f? The issue is that an expression can have an arbitrary type (Eigen uses expression templates), like CwiseBinaryOp<...CwiseBinaryOp<...>> and so on. This is part of a larger problem in which I have a utility make-like function which takes a lvalue and binds it to a const reference expression in a class. If the expression is a rvalue, then all bets are off, since reference binding is not propagating via a constructor argument, so I want to forbid passing rvalue Eigen expressions.

解决方案

I think I found what was going on: the result of the expression template A + A was a const, so there was a CV-mismatch. Adding const to the second overload does it:

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

这篇关于禁用特征表达式与const引用的临时绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆