- Rvalue reference overload confusion - 6 Updates
| Paavo Helde <eesnimi@osa.pri.ee>: Jan 26 03:55PM +0200 Today I was surprised by an unexpected conversion from NSVC++ 2019. The code example is here: #include <iostream> class A { public: A(size_t) {} }; enum e { e1, e2, e3 }; class B { public: B(e) {} }; void foo(A&&) { std::cout << "Overload A\n"; } void foo(const B&) { std::cout << "Overload B\n"; } int main() { foo(e1); } MSVC++ 2019 compiles this fine and chooses overload A. g++ refuses to compile it and reports an ambiguity. Who is right? PS. If one replaces foo(A&&) with foo(const A&), then also MSVC reports an ambiguity. |
| "Öö Tiib" <ootiib@hot.ee>: Jan 26 06:43AM -0800 On Wednesday, 26 January 2022 at 15:55:46 UTC+2, Paavo Helde wrote: > compile it and reports an ambiguity. Who is right? > PS. If one replaces foo(A&&) with foo(const A&), then also MSVC reports > an ambiguity. I suspect gcc is correct but cant bring normative proofs. The MSVC has its legacy of being overly permissive there. I'm not even sure if it has stopped accepting rvalues to initialise non-const lvalue references yet. Anyway I like whatever diagnostics of doubt about whatever implicit conversions as these keep causing major illusions and confusions. |
| Bonita Montero <Bonita.Montero@gmail.com>: Jan 26 03:50PM +0100 Am 26.01.2022 um 15:43 schrieb Öö Tiib: > accepting rvalues to initialise non-const lvalue references yet. Anyway I > like whatever diagnostics of doubt about whatever implicit conversions > as these keep causing major illusions and confusions. Maybe it would help to use a scoped enum which hasn't an implicit conversion to int. |
| Paavo Helde <eesnimi@osa.pri.ee>: Jan 26 06:26PM +0200 26.01.2022 16:50 Bonita Montero kirjutas: >>> Today I was surprised by an unexpected conversion > Maybe it would help to use a scoped enum which hasn't an implicit > conversion to int. Yes, in new code scoped enums should be certainly preferred. Changing them the scoped enums in old codebases is harder. |
| Bonita Montero <Bonita.Montero@gmail.com>: Jan 26 05:32PM +0100 Am 26.01.2022 um 17:26 schrieb Paavo Helde: >> conversion to int. > Yes, in new code scoped enums should be certainly preferred. Changing > them the scoped enums in old codebases is harder. When I have enums which are part of a namespace I mostly don't use them, when I have enums which are part of a class I never use them. |
| Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 26 08:46AM -0800 On 1/26/2022 5:55 AM, Paavo Helde wrote: > compile it and reports an ambiguity. Who is right? > PS. If one replaces foo(A&&) with foo(const A&), then also MSVC reports > an ambiguity. The example can be simplified by taking `enum` out of the picture #include <iostream> class A { public: A(int) {} }; class B { public: B(int) {} }; void foo(A&&) { std::cout << "Overload A\n"; } void foo(const B&) { std::cout << "Overload B\n"; } int main() { foo(0); } it will still exhibit the same behavior, but now it is fully "symmetrical" with regard to `A` and `B`. Experimenting with the example shows that MSVC seems to over-prioritize the existing rule that binding rvalue reference to an rvalue is better than binding an lvalue reference http://eel.is/c++draft/over.ics.rank#3.2.3 However, in this case the two conversion sequences are incomparable because they involve _different_ user-defined conversions. (In order to be comparable they should use the same user-defined conversion.) This is what is supposed to be recognized as an ambiguity by the compiler http://eel.is/c++draft/over.ics.rank#3.3 If we simplify the example to a mere #include <iostream> class A { public: A(int) {} }; void foo(A&&) { std::cout << "Overload rvalue\n"; } void foo(const A&) { std::cout << "Overload lvalue\n"; } int main() { foo(0); } both candidate paths will use the the same user-defined conversion. The call is no longer ambiguous, since the above "rvalue-is-better-than-lvalue" logic kicks in. -- Best regards, Andrey Tarasevich |
| You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment