Skip to content

Overload resolution ambiguity between std::data and boost::data on boost::span #206

@DiegoBaldassarMilleuno

Description

@DiegoBaldassarMilleuno

The following code fails to compile (in C++17 and up) because of an ambiguous resolution between std::data and boost::data (ADL-found):

#include <boost/core/span.hpp>
#include <iterator>

int* f(boost::span<int> spn) {
	using std::data;
	return data(spn);
}
Output of GCC15:
./test.cpp: In function 'int* f(boost::span<int>)':
./test.cpp:19:20: error: call of overloaded 'data(boost::span<int>&)' is ambiguous
   19 |         return data(spn);
      |                ~~~~^~~~~
./test.cpp:19:20: note: there are 8 candidates
In file included from /opt/homebrew/Cellar/gcc/15.2.0/include/c++/15/array:46,
                 from boost_1_89_0/boost/core/span.hpp:13,
                 from ./test.cpp:1:
/opt/homebrew/Cellar/gcc/15.2.0/include/c++/15/bits/range_access.h:335:5: note: candidate 1: 'constexpr decltype (__cont.data()) std::data(const _Container&) [with _Container = boost::span<int>; decltype (__cont.data()) = int*]'
  335 |     data(const _Container& __cont) noexcept(noexcept(__cont.data()))
      |     ^~~~
/opt/homebrew/Cellar/gcc/15.2.0/include/c++/15/bits/range_access.h:324:5: note: candidate 2: 'constexpr decltype (__cont.data()) std::data(_Container&) [with _Container = boost::span<int>; decltype (__cont.data()) = int*]'
  324 |     data(_Container& __cont) noexcept(noexcept(__cont.data()))
      |     ^~~~
In file included from boost_1_89_0/boost/core/span.hpp:12:
boost_1_89_0/boost/core/data.hpp:18:1: note: candidate 3: 'constexpr decltype (c.data()) boost::data(C&) [with C =span<int>; decltype (c.data()) = int*]'
   18 | data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
      | ^~~~
boost_1_89_0/boost/core/data.hpp:25:1: note: candidate 4: 'constexpr decltype (c.data()) boost::data(const C&) [with C = span<int>; decltype (c.data()) = int*]'
   25 | data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
      | ^~~~

This would not occur with std::span.
Tested on Boost 1.89.0. This happens consistently with recent enough versions of GCC, clang or Apple clang.

A few possible solutions:

  1. move span to boost::core:: #196;
  2. Adding a couple of extra overloads to data for boost::span and const boost::span;
  3. Replacing the definitions for boost::data in boost/core/data.hpp only in C++17 mode and up with a single using std::data; in the boost namespace.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions