c++ 如何通过引用传递一个XTensor数组,以便可以就地修改它?

vngu2lb8  于 2023-02-14  发布在  其他
关注(0)|答案(1)|浏览(165)

我正在使用C++库XTensor。我想在函数中就地修改数组。

void modifyXArray(xt::xarray<double>& arr) {
    arr += 1;
}

但是,使用此功能时:

auto tmp = xt::linspace(0, 1, 100);
modifyXArray(tmp);

我得到错误:

/home/tom/src/xtensor-interp/tests/test_interpolator.cpp: In member function ‘virtual void Foo_Bar_Test::TestBody()’:
/home/tom/src/xtensor-interp/tests/test_interpolator.cpp:92:18: error: cannot bind non-const lvalue reference of type ‘xt::xarray<double>&’ {aka ‘xt::xarray_container<xt::uvector<double, std::allocator<double> >, xt::layout_type::row_major, xt::svector<long unsigned int, 4, std::allocator<long unsigned int>, true>, xt::xtensor_expression_tag>&’} to an rvalue of type ‘xt::xarray<double>’ {aka ‘xt::xarray_container<xt::uvector<double, std::allocator<double> >, xt::layout_type::row_major, xt::svector<long unsigned int, 4, std::allocator<long unsigned int>, true>, xt::xtensor_expression_tag>’}
   92 |     modifyXArray(tmp);
      |                  ^~~
In file included from /home/tom/src/xtensor-interp/XTensorInterp/XTensorInterp/interpolator.h:11,
                 from /home/tom/src/xtensor-interp/tests/test_interpolator.cpp:1:
/home/tom/src/xtensor-interp/build/Release/_deps/xtensor-src/include/xtensor/xarray.hpp:501:12: note:   after user-defined conversion: ‘xt::xarray_container<EC, L, SC, Tag>::xarray_container(const xt::xexpression<E>&) [with E = xt::xgenerator<xt::detail::arange_generator<double, int, double>, int, std::array<long unsigned int, 1> >; EC = xt::uvector<double, std::allocator<double> >; xt::layout_type L = xt::layout_type::row_major; SC = xt::svector<long unsigned int, 4, std::allocator<long unsigned int>, true>; Tag = xt::xtensor_expression_tag]’
  501 |     inline xarray_container<EC, L, SC, Tag>::xarray_container(const xexpression<E>& e)
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/tom/src/xtensor-interp/tests/test_interpolator.cpp:85:39: note:   initializing argument 1 of ‘void modifyXArray(xt::xarray<double>&)’
   85 | void modifyXArray(xt::xarray<double>& arr) {
      |                   ~~~~~~~~~~~~~~~~~~~~^~~

如果将数组标记为const,则可以通过引用传入数组,但不能修改它。

flvtvl50

flvtvl501#

tmp不是一个xt::xarray,它是一个可以自动转换成数组的builder。当你把它传递给modifyXArray时,它会尝试做这个转换(请参见错误消息中的after user-defined conversion: ‘xt::xarray_container...),但转换返回临时(右值),并且不能将临时值绑定到非常数引用(即使你这样做了,临时变量也会被丢弃,你的原始变量不会被修改)。你需要在传递给modifyXArray之前强制转换成数组。这与不使用auto一样简单:

xt::xarray<double> tmp = xt::linspace(0, 1, 100);
modifyXArray(tmp);

现在,当您构造tmp时会发生转换,并且您现在有了一个可以传递给modifyXArray的非临时数组

相关问题