Date: Thu, 31 Dec 2020 09:54:44 +0800
Presumably, `enum A;` would be `enum A{};` while `enum B;` would be `enum
B{};`. Since the conversion function `operator A() &{ return A{}; }` which
has been qualified by ref-qualifier `&`, that means the implicit parameter
object shall be an lvalue. `S{}` will be converted to an *xvalue*. So, `
void foo(A)` is never a candidate function. That's all.
Hani Deek via Std-Discussion <std-discussion_at_[hidden]>
于2020年12月31日周四 上午3:22写道:
> The following example produces quite conflicting results
> https://godbolt.org/z/PExfM1.
> It is accepted by msvc and icc, but rejected by gcc and clang. Because of
> these different results, in addition to the point made by Lénárd Szolnoki
> in his last message, I still do not know the correct answer to this whole
> issue.
>
> enum A;
> enum B;
>
> struct S
> {
> operator A() &{ return A{}; }
> operator B() &&{ return B{}; }
> };
>
> void foo(A) {}
> void foo(B) {}
>
> int main()
> {
> foo(S{});
> }
>
> ------------------------------
> Hani Deek via Std-Discussion <std-discussion_at_[hidden]>
>
> Hello,
>
>
> With MSVC, the following code compiles. The char overload is selected by
> overload resolution.
>
> struct S
> {
> operator int() const & { return 0; }
> operator char() && { return 0; }
> };
>
> void foo(int) {}
> void foo(char) {}
>
> int main()
> {
> foo(S{}); //OK, calls 'void foo(char)'.
> }
>
> However, the following code won't compile.
>
> struct S
> {
> int i = 0;
> operator const int &() const & { return i; }
> operator int &&() && { return (int &&)(i); }
> };
>
> void foo(const int &) {}
> void foo(int &&) {}
>
> int main()
> {
> foo(S{}); //error C2668: 'foo': ambiguous call to overloaded function
> //message : could be 'void foo(int &&)'
> //message : or 'void foo(const int &)'
> }
>
> What is exactly the difference that makes the second sample fail to
> compile?
>
> Given that 'operator int &&() &&' is an exact match to the conversion
> required to call 'void foo(int &&)', I expected the compiler to select
> it. It is strange if the C++ rules will not allow the compiler to select a
> conversion function that exactly matches the required conversion, both in
> terms of the provided argument 'S &&' and the result of conversion 'int &&
> '.
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
B{};`. Since the conversion function `operator A() &{ return A{}; }` which
has been qualified by ref-qualifier `&`, that means the implicit parameter
object shall be an lvalue. `S{}` will be converted to an *xvalue*. So, `
void foo(A)` is never a candidate function. That's all.
Hani Deek via Std-Discussion <std-discussion_at_[hidden]>
于2020年12月31日周四 上午3:22写道:
> The following example produces quite conflicting results
> https://godbolt.org/z/PExfM1.
> It is accepted by msvc and icc, but rejected by gcc and clang. Because of
> these different results, in addition to the point made by Lénárd Szolnoki
> in his last message, I still do not know the correct answer to this whole
> issue.
>
> enum A;
> enum B;
>
> struct S
> {
> operator A() &{ return A{}; }
> operator B() &&{ return B{}; }
> };
>
> void foo(A) {}
> void foo(B) {}
>
> int main()
> {
> foo(S{});
> }
>
> ------------------------------
> Hani Deek via Std-Discussion <std-discussion_at_[hidden]>
>
> Hello,
>
>
> With MSVC, the following code compiles. The char overload is selected by
> overload resolution.
>
> struct S
> {
> operator int() const & { return 0; }
> operator char() && { return 0; }
> };
>
> void foo(int) {}
> void foo(char) {}
>
> int main()
> {
> foo(S{}); //OK, calls 'void foo(char)'.
> }
>
> However, the following code won't compile.
>
> struct S
> {
> int i = 0;
> operator const int &() const & { return i; }
> operator int &&() && { return (int &&)(i); }
> };
>
> void foo(const int &) {}
> void foo(int &&) {}
>
> int main()
> {
> foo(S{}); //error C2668: 'foo': ambiguous call to overloaded function
> //message : could be 'void foo(int &&)'
> //message : or 'void foo(const int &)'
> }
>
> What is exactly the difference that makes the second sample fail to
> compile?
>
> Given that 'operator int &&() &&' is an exact match to the conversion
> required to call 'void foo(int &&)', I expected the compiler to select
> it. It is strange if the C++ rules will not allow the compiler to select a
> conversion function that exactly matches the required conversion, both in
> terms of the provided argument 'S &&' and the result of conversion 'int &&
> '.
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
Received on 2020-12-30 19:54:58