Why can I prevent implicit conversions for primitives but not user-defined types?
High-integrity C ++ standards assume that rvalue arguments to functions can be removed, which prevents implicit conversions.
I've found that the behavior for primitives and custom types is very different.
struct A { };
struct B { B(const A& ) {} };
template <class T>
void foo(const T&&) = delete; // 1 - deleted rvalue overload. const intentional.
void foo(B) {} // 2
void foo(int) {} // 3
int main(int argc, char* argv[])
{
A a;
foo(a); // This resolves to 2
foo(3.3); // This resolves to 1
foo(2); // This resolves to 3 (as expected).
}
Why does remote rvalue overload prevent implicit conversion to int, but not from one user-defined type to another?
source to share
There is no processing difference in your code between custom types and primitive types. The difference between the behavior of these two lines:
foo(a);
foo(3.3);
is what a
is an lvalue and 3.3
is an r-value. The rvalue argument matches your overload 1
(which only accepts rvalues), the lvalue argument doesn't matter.
If you try to call foo<A>
with an rvalue argument it will also match 1
and fail, eg. foo(A{});
...
source to share
The high integrity C ++ standards show that rvalue arguments to a function can be removed, which prevents implicit conversions.
No, only the link overload forwarder disables ICS (Implicit Sequence) for all other overloads in the overload set. Make a forwarding link and see ICS disabled (Coliru Link)
template <class T>
void foo(const T&&) = delete; // introduces a qualification match
The above code adds qualification matching to the overload. So ICS is still in the game.
Why foo(3.3)
it failed, since 3.3
is a prvalue of type double
which would better match rvalue overload than conversion to int
. Because qualification fit is rated better than conversion fit
source to share
There are 3 possible overloads
- 1 is viable.
- 2 viable
- 3 not
2 is the best match (pattern (not an exact match) vs. normal method (with one user specifying the transformation)).
You can look at http://en.cppreference.com/w/cpp/language/overload_resolution to see the full set of rules required
source to share