Repository: xtensor-stack/xtensor (language: python)

Issue:
Cannot use a `xt::index_view` of a const tensor
The following piece of code to compile.

```cpp
#include <xtensor/xtensor.hpp>
#include <xtensor/xindex_view.hpp>

int main() {
    xt::xtensor<int, 1> const a = {1, 2};
    auto v = xt::index_view(a, std::vector<std::size_t>{2, 1});
    return v[0];
}
```
```
 error: binding reference of type 'xt::xindex_view<const xt::xtensor_container<xt::uvector<int, std::allocator<int> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>&, std::vector<long unsigned int, std::allocator<long unsigned int> > >::reference' {aka 'int&'} to 'const xt::uvector<int, std::allocator<int> >::value_type' {aka 'const int'} discards qualifiers
  402 |         return m_e[m_indices[idx]];
```

[compiler explorer](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:14,endLineNumber:10,positionColumn:14,positionLineNumber:10,selectionStartColumn:14,selectionStartLineNumber:10,startColumn:14,startLineNumber:10),source:'%23include+%3Cxtensor/xtensor.hpp%3E%0A%23include+%3Cxtensor/xarray.hpp%3E%0A%23include+%3Cxtensor/xfixed.hpp%3E%0A%23include+%3Cxtensor/xview.hpp%3E%0A%23include+%3Cxtensor/xindex_view.hpp%3E%0A%0A%0Aint+main()+%7B%0A++++//+xt::xtensor_fixed%3Cdouble,+xt::xshape%3C2%3E%3E+const+a+%3D+%7B1.,+2.%7D%3B%0A++++xt::xtensor%3Cint,+1%3E+const+a+%3D+%7B1,+2%7D%3B%0A++++//+xt::xarray%3Cdouble%3E+const+a+%3D+%7B1.,+2.%7D%3B%0A%0A++++auto+v+%3D+xt::index_view(a,+std::vector%3Cstd::size_t%3E%7B2,+1%7D)%3B%0A++++//+auto+v+%3D+xt::view(a,+1)%3B%0A++++return+v%5B0%5D%3B%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:47.82686451414494,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:g122,deviceViewOpen:'1',filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!((name:xsimd,ver:trunk),(name:xtensor,ver:trunk),(name:xtl,ver:trunk)),options:'-O1+-std%3Dc%2B%2B14',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+gcc+12.2+(Editor+%231)',t:'0')),header:(),k:52.17313548585507,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'1',compilationPanelShown:'0',compiler:g122,compilerOutShown:'0',execArgs:'',execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!((name:xsimd,ver:trunk),(name:xtensor,ver:trunk),(name:xtl,ver:trunk)),options:'-O1+-std%3Dc%2B%2B14',source:1,stdinPanelShown:'1',tree:'1',wrap:'1'),l:'5',n:'0',o:'Executor+x86-64+gcc+12.2+(C%2B%2B,+Editor+%231)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:52.17313548585507,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

Because `xindex_view::reference` is an `int&` but the array data is `const int`.


Discussion / hints:

Fix patch:
diff --git a/include/xtensor/xindex_view.hpp b/include/xtensor/xindex_view.hpp
index 48330e819..1a298a4ed 100644
--- a/include/xtensor/xindex_view.hpp
+++ b/include/xtensor/xindex_view.hpp
@@ -102,7 +102,7 @@ namespace xt
         using expression_tag = typename extension_base::expression_tag;
 
         using value_type = typename xexpression_type::value_type;
-        using reference = typename xexpression_type::reference;
+        using reference = inner_reference_t<CT>;
         using const_reference = typename xexpression_type::const_reference;
         using pointer = typename xexpression_type::pointer;
         using const_pointer = typename xexpression_type::const_pointer;


Test patch:
diff --git a/test/test_xindex_view.cpp b/test/test_xindex_view.cpp
index 8bde8a27e..d01b9764f 100644
--- a/test/test_xindex_view.cpp
+++ b/test/test_xindex_view.cpp
@@ -55,6 +55,15 @@ namespace xt
         EXPECT_EQ(3, e(2, 2));
     }
 
+    TEST(xindex_view, indices_const)
+    {
+        xarray<double> const e = xt::random::rand<double>({3, 3});
+        auto v = index_view(e, {{1ul, 1ul}, {1ul, 2ul}, {2ul, 2ul}});
+        EXPECT_EQ(e(1, 1), v(0));
+        auto const vc = index_view(e, {{1ul, 1ul}, {1ul, 2ul}, {2ul, 2ul}});
+        EXPECT_EQ(vc(0), v(0));
+    }
+
     TEST(xindex_view, boolean)
     {
         xarray<double> e = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};