禁用特征表达式与const引用的临时绑定 [英] Disable temporary binding of Eigen expression to const references
问题描述
我试图写一个函数,只接受通过 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 delete
d 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), likeCwiseBinaryOp<...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 aconst
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屋!