dsharlet / array

C++ multidimensional arrays in the spirit of the STL
Apache License 2.0
198 stars 15 forks source link

call of overloaded ‘for_each_value_in_order<(nda::shape<>::rank() - 1)>(nda::shape<>::index_type, void (&)(const int&, int&), std::pair<const int*, std::tuple<> >&, std::pair<int*, std::tuple<> >&)’ is ambiguous #67

Closed Mr-doooog closed 2 years ago

Mr-doooog commented 2 years ago

mkdir -p obj/test g++ -I. -c -o obj/test/algorithm.o test/algorithm.cpp -O2 -ffast-math -fstrict-aliasing -march=native -std=c++14 -Wall In file included from test/algorithm.cpp:15: ./array.h: In instantiation of ‘void nda::for_each_value_in_order(const Shape&, const ShapeA&, PtrA, const ShapeB&, PtrB, Fn&&) [with Shape = nda::shape<>; ShapeA = nda::shape<>; PtrA = const int*; ShapeB = nda::shape<>; PtrB = int*; Fn = void (&)(const int&, int&); <template-parameter-1-7> = void]’: ./array.h:1796:28: required from ‘static void nda::copy_shape_traits<ShapeSrc, ShapeDst>::for_each_value(const ShapeSrc&, TSrc, const ShapeDst&, TDst, Fn&&) [with Fn = void (&)(const int&, int&); TSrc = const int*; TDst = int*; ShapeSrc = nda::shape<>; ShapeDst = nda::shape<>]’ ./array.h:2598:56: required from ‘void nda::copy(const nda::array_ref<TSrc, ShapeSrc>&, const nda::array_ref<TDst, ShapeDst>&) [with TSrc = const int; TDst = int; ShapeSrc = nda::shape<>; ShapeDst = nda::shape<>; <template-parameter-1-5> = void]’ ./array.h:2614:7: required from ‘void nda::copy(const nda::array<TSrc, ShapeSrc, AllocSrc>&, nda::array<TDst, ShapeDst, AllocDst>&) [with TSrc = int; TDst = int; ShapeSrc = nda::shape<>; ShapeDst = nda::shape<>; AllocSrc = std::allocator<int>; AllocDst = std::allocator<int>; <template-parameter-1-7> = void]’ test/algorithm.cpp:76:12: required from here ./array.h:1602:55: error: call of overloaded ‘for_each_value_in_order<(nda::shape<>::rank() - 1)>(nda::shape<>::index_type, void (&)(const int&, int&), std::pair<const int*, std::tuple<> >&, std::pair<int*, std::tuple<> >&)’ is ambiguous 1602 | internal::for_each_value_in_order<Shape::rank() - 1>(shape.extent(), fn, a, b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ ./array.h:1361:41: note: candidate: ‘void nda::internal::for_each_value_in_order(const ExtentType&, Fn&&, Ptrs ...) [with long unsigned int D = 18446744073709551615; ExtentType = std::tuple<>; Fn = void (&)(const int&, int&); Ptrs = {std::pair<const int*, std::tuple<> >, std::pair<int*, std::tuple<> >}]’ 1361 | NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_value_in_order( | ^~~~~~~~~~~~~~~~~~~~~~~ ./array.h:1369:41: note: candidate: ‘void nda::internal::for_each_value_in_order(const std::tuple<>&, Fn&&, Ptrs ...) [with long unsigned int D = 18446744073709551615; Fn = void (&)(const int&, int&); Ptrs = {std::pair<const int*, std::tuple<> >, std::pair<int*, std::tuple<> >}]’ 1369 | NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_value_in_order( | ^~~~~~~~~~~~~~~~~~~~~~~ ./array.h: In instantiation of ‘void nda::for_each_value_in_order(const Shape&, Ptr, Fn&&) [with Shape = nda::shape<>; Ptr = int*; Fn = nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]::<lambda(int&)>&; <template-parameter-1-4> = void]’: ./array.h:1771:28: required from ‘static void nda::shape_traits<Shape>::for_each_value(const Shape&, Ptr, Fn&&) [with Ptr = int*; Fn = nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]::<lambda(int&)>&; Shape = nda::shape<>]’ ./array.h:1978:38: required from ‘void nda::array_ref<T, Shape>::for_each_value(Fn&&) const [with Fn = nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]::<lambda(int&)>; <template-parameter-2-2> = void; T = int; Shape = nda::shape<>]’ ./array.h:2747:3: required from ‘void nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]’ ./array.h:2752:11: required from ‘void nda::generate(nda::array<T, Shape, Alloc>&, Generator&&) [with T = int; Shape = nda::shape<>; Alloc = std::allocator<int>; Generator = int (&)(); <template-parameter-1-5> = int]’ test/algorithm.cpp:73:19: required from here ./array.h:1585:55: error: call of overloaded ‘for_each_value_in_order<(nda::shape<>::rank() - 1)>(nda::shape<>::index_type, nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]::<lambda(int&)>&, std::pair<int*, std::tuple<> >&)’ is ambiguous 1585 | internal::for_each_value_in_order<Shape::rank() - 1>(shape.extent(), fn, base_and_stride); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./array.h:1361:41: note: candidate: ‘void nda::internal::for_each_value_in_order(const ExtentType&, Fn&&, Ptrs ...) [with long unsigned int D = 18446744073709551615; ExtentType = std::tuple<>; Fn = nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]::<lambda(int&)>&; Ptrs = {std::pair<int*, std::tuple<> >}]’ 1361 | NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_value_in_order( | ^~~~~~~~~~~~~~~~~~~~~~~ ./array.h:1369:41: note: candidate: ‘void nda::internal::for_each_value_in_order(const std::tuple<>&, Fn&&, Ptrs ...) [with long unsigned int D = 18446744073709551615; Fn = nda::generate(const nda::array_ref<T, Shape>&, Generator&&) [with T = int; Shape = nda::shape<>; Generator = int (&)(); <template-parameter-1-4> = int]::<lambda(int&)>&; Ptrs = {std::pair<int*, std::tuple<> >}]’ 1369 | NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_value_in_order( | ^~~~~~~~~~~~~~~~~~~~~~~ ./array.h: In instantiation of ‘void nda::for_each_value_in_order(const Shape&, const ShapeA&, PtrA, const ShapeB&, PtrB, Fn&&) [with Shape = nda::shape<>; ShapeA = nda::shape<>; PtrA = const int*; ShapeB = nda::shape<>; PtrB = const int*; Fn = nda::array_ref<T, Shape>::operator!=(const nda::array_ref<T, Shape>&) const [with T = const int; Shape = nda::shape<>]::<lambda(nda::array_ref<const int, nda::shape<> >::const_reference, nda::array_ref<const int, nda::shape<> >::const_reference)>&; <template-parameter-1-7> = void]’: ./array.h:1796:28: required from ‘static void nda::copy_shape_traits<ShapeSrc, ShapeDst>::for_each_value(const ShapeSrc&, TSrc, const ShapeDst&, TDst, Fn&&) [with Fn = nda::array_ref<T, Shape>::operator!=(const nda::array_ref<T, Shape>&) const [with T = const int; Shape = nda::shape<>]::<lambda(nda::array_ref<const int, nda::shape<> >::const_reference, nda::array_ref<const int, nda::shape<> >::const_reference)>; TSrc = const int*; TDst = const int*; ShapeSrc = nda::shape<>; ShapeDst = nda::shape<>]’

jiawen commented 2 years ago

This is very hard to parse. What did you run as your top level command? Can you also say what platform you're on and what version of gcc you're using?

dsharlet commented 2 years ago

This just looks like make test, but yes, the gcc version would be helpful. I remember testing gcc for a while via Travis so it at least worked at some point with some version of gcc.

On Sun, Jul 10, 2022 at 4:07 PM Jiawen (Kevin) Chen < @.***> wrote:

This is very hard to parse. What did you run as your top level command? Can you also say what platform you're on and what version of gcc you're using?

— Reply to this email directly, view it on GitHub https://github.com/dsharlet/array/issues/67#issuecomment-1179818212, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQUSAALDJKPOTXIETBNL43VTNJT3ANCNFSM523YNWUA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

dsharlet commented 2 years ago

I was able to reproduce this on gcc 9.4 on Ubuntu. Unfortunately this seems like a pretty basic compiler bug and I'm not sure if there is a reasonable workaround. I think according to the standard, this is clearly not an ambiguous overload, and later versions of GCC don't have this problem (neither does clang).

dsharlet commented 2 years ago

I actually did find a workaround for this and other issues that old GCC versions struggled with. It was actually make_compact_dims that seemed harder to help with ambiguous overloads for, but then I realized that could be implemented without relying on overloading at all. #73 should fix this.