问题
C++编译报错cannot bind non-const lvalue reference of type ...
后续检查发现是出参发生了隐式地址转换,而入参数为常引用不受影响。
复现
代码举例说明
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>
using namespace Eigen;
void twice(const Tensor<int,2>& in, Tensor<int,2>& out)
{
out = in * 2;
}
int main()
{
TensorFixedSize<int, Sizes<2, 2>> in;
in.setConstant(1);
TensorFixedSize<int, Sizes<2, 2>> out;
twice(in, out);
std::cout << out << std::endl;
return 0;
}
报错
<source>: In function 'int main()':
<source>:14:15: error: cannot bind non-const lvalue reference of type 'Eigen::Tensor<int, 2>&' to an rvalue of type 'Eigen::Tensor<int, 2>'
14 | twice(in, out);
| ^~~
In file included from /opt/compiler-explorer/libs/eigen/v3.4.0/unsupported/Eigen/CXX11/Tensor:127,
from <source>:3:
/opt/compiler-explorer/libs/eigen/v3.4.0/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:394:25: note: after user-defined conversion: 'Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>::Tensor(const Eigen::TensorBase<OtherDerived, 1>&) [with OtherDerived = Eigen::TensorFixedSize<int, Eigen::Sizes<2, 2> >; Scalar_ = int; int NumIndices_ = 2; int Options_ = 0; IndexType_ = long int]'
394 | EIGEN_STRONG_INLINE Tensor(const TensorBase<OtherDerived, WriteAccessors>& other)
| ^~~~~~
<source>:5:52: note: initializing argument 2 of 'void twice(const Eigen::Tensor<int, 2>&, Eigen::Tensor<int, 2>&)'
5 | void twice(const Tensor<int,2>& in, Tensor<int,2>& out)
| ~~~~~~~~~~~~~~~^~~
分析
上述例子比较不明显,编译器不会明显曝出两明显不同的类型错误。
左值TensorFixedSize
输入时隐式转换为Tesnor
右值,对应函数:
作为const reference入参没问题,作为reference出参自然会报错。