Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload selection between pointer and reference for double argument when passing 0 literal

Tags:

c++

c++11

Consider the following two overloads:

template <T> void foo(T * d);
template <T> void foo(const T & d);

If used like this:

foo<double>(0);

Which overload will be called? Can you please point-me at the spec paragraph that define this behavior?

ps: From some quick tests it seems that the literal zero matches the nullptr, therefore the pointer overload is selected, but I'd like to know from the language spec.

(edit) Added const reference, that's the actual case.

like image 740
Felipe Lavratti Avatar asked Nov 30 '25 06:11

Felipe Lavratti


1 Answers

From http://en.cppreference.com/w/cpp/language/overload_resolution

Best Viable functions:

1) there is at least one argument of F1 whose implicit conversion is better than the corresponding implicit conversion for that argument of F2
2) or. if not that, (only in context of non-class initialization by conversion), the standard conversion sequence from the return type of F1 to the type being initialized is better than the standard conversion sequence from the return type of F2
3) or, if not that, F1 is a non-template function while F2 is a template specialization
4) or, if not that, F1 and F2 are both template specializations and F1 is more specialized according to the partial ordering rules for template specializations

And for Ranking of implicit conversion sequences

Each type of standard conversion sequence is assigned one of three ranks:

1) Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, function pointer conversion, (since C++17) user-defined conversion of class type to the same class
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base

So for

f(double*);       // null pointer conversion
f(const double&); // Floating–integral conversions

f(0); // Ambiguous call

With template

template <T> void foo(T*);       // #1 // null pointer conversion
template <T> void foo(const T&); // #2 // Floating–integral conversions

foo<double>(0); // #1

As #1 is more specialized than #2.

like image 73
Jarod42 Avatar answered Dec 01 '25 19:12

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!