Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::span overload resolution

I want to pass a C-style array to a function taking a std::span, but overload resolution chooses to convert the array to bool instead. Is this behavior required by the standard, or is it a compiler issue? (I tried several compilers, and they all do the same thing. https://godbolt.org/z/8rxTWPd3K)

When TEST is defined as 0, so the second overload is not defined, the array is converted to std::span as I expected, so clearly that is a good match.

If the conversion to std::span isn't better than the conversion to bool, I would have expected it to be ambiguous, rather than choosing the wrong one.

It is easy to change the call to workaround the problem, but since there is no warning, it isn't obvious to the person writing the call what the problem is, or how to fix it. Is there a way to change the function definition, or add an additional overload, that would be a better match for the C-style array to avoid the conversion to bool? If not, is there a way to change it to be ambiguous so that the caller would get an error?

(Obviously, this is a stripped down test case. In the actual code, there are additional parameters, and both overloads do the same thing, so it really is appropriate that they have the same name.)

#include <span>

#define TEST 1

extern void f(std::span<const unsigned>);

#if TEST
extern void f(bool c);
#endif

static const unsigned a[] = { 1, 2 };

void q()
{
    f(a);
}
like image 744
prl Avatar asked Jul 16 '26 22:07

prl


1 Answers

I would still like to know why bool is a better match than std::span

From overload resolution, you might see in Ranking_of_implicit_conversion_sequences that standard conversion sequence (boolean conversion) is "better" than a user-defined conversion sequence.

Is there a way to change the function definition or add an additional overload that would be a better match for the C array to avoid the conversion to bool?

You might add an overload for a C-array:

template<typename T, std::size_t N>
void f(const T (&arr)[N] ) { f(std::span(arr)); }
like image 200
Jarod42 Avatar answered Jul 18 '26 13:07

Jarod42



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!