xtensor-stack / xtensor

C++ tensors with broadcasting and lazy computing
BSD 3-Clause "New" or "Revised" License
3.33k stars 398 forks source link

Example code does not build #331

Closed wolfv closed 7 years ago

wolfv commented 7 years ago
#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"

int main() {
    xt::xarray<double> arr1
      {{1.0, 2.0, 3.0},
       {2.0, 5.0, 7.0},
       {2.0, 5.0, 7.0}};

    xt::xarray<double> arr2
      {5.0, 6.0, 7.0};

    xt::xarray<double> res = xt::view(arr1, 1) + arr2;

    std::cout << res;
}

Failes to compile on ubuntu 16.04 with g++5.4 with

/usr/local/include/xtensor/xview.hpp:338:113: error: invalid initialization of non-const reference of type ‘xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, std::vector<long unsigned int> >&’ from an rvalue of type ‘xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, std::vector<long unsigned int> >’

Maybe someone else can confirm?

SylvainCorlay commented 7 years ago

Confirmed

SylvainCorlay commented 7 years ago
SylvainCorlay commented 7 years ago

@JohanMabille, any clue?

JohanMabille commented 7 years ago

I can't test it now but it looks like the generated move constructor of xview (called when building the xfunction for operator+) tries to move the m_e member of the moved xview, making it appear as an rvalue.

SylvainCorlay commented 7 years ago

I confirm that doing auto v = xt::view(arr1, 1) and passing it to the next line work.

SylvainCorlay commented 7 years ago

Yes that is it. We need to implement move constructors for expressions holding closures, which only move held closures when they are value types.

JohanMabille commented 7 years ago

After further investigations, the problem comes from the xview constructor, which is called with no slice argument instead of the copy constructor. Adding a template parameter before the template parameter pack fixes the problem.