Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8253165
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T00:47:01+00:00 2026-06-08T00:47:01+00:00

Given the following code (in GCC 4.3) , why is the conversion to reference

  • 0

Given the following code (in GCC 4.3) , why is the conversion to reference called in both cases?

class A { };

class B {
public:
  operator A() {}
  operator A&() {}
};

int main() {
  B b;
  (A) b;
  (A&) b;
}

http://ideone.com/d6iF8

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T00:47:03+00:00Added an answer on June 8, 2026 at 12:47 am

    Your code is ambiguous and should not compile (it is ill-formed per 13.3.3:2).

    lvalue-to-rvalue conversion has the same rank as identity conversion, so (per 13.3.3:1) there is no way to choose between them.

    Comeau C++ (probably the most standards-compliant compiler) gives the following error:

    "ComeauTest.c", line 11: error: more than one user-defined conversion from "B" to
              "A" applies:
                function "B::operator A()"
                function "B::operator A &()"
        (A) b;
            ^
    

    Here’s the relevant text from the standard:

    c++11

    13.3.3 Best viable function [over.match.best]

    […] Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 […]

    2 –
    If there is exactly one viable function that is a better function than all other viable functions, then it is the
    one selected by overload resolution; otherwise the call is ill-formed.

    The definitions themselves are complicated, but there’s two things to note with user-defined conversions:

    First, the application of user-defined conversion as a conversion sequence is specified to decompose into a sequence S_a - U - S_b of a standard conversion sequence followed by a user-defined conversion followed by another standard conversion sequence. This covers all the cases; you can’t have more than one user-defined conversion in a conversion sequence, and a standard conversion sequence can be the “identity conversion” i.e. no conversion required.

    Second, when comparing user-defined conversion sequences the only part that matters is the second standard conversion sequence. This is in 13.3.3:

    c++11

    13.3.3 Best viable function [over.match.best]

    […] a viable function F1 is defined to be a better function than another viable function
    F2 if […]

    • the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the
      standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the
      entity being initialized) is a better conversion sequence than the standard conversion sequence from
      the return type of F2 to the destination type.

    and in 13.3.3.2:

    c++11

    13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]

    3 – Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
    the following rules applies: […]

    • User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or aggregate
      initialization and the second standard conversion sequence of U1 is better than the second standard
      conversion sequence of U2.

    So when comparing conversion sequences U1 = (S1_a - U'1 - S1_b) and U2 = (S2_a - U'2 - S2_b) the only thing that matters is the relative rank of S1_b and S2_b; the standard conversion sequences required to arrive at the parameter of the user-defined conversions do not matter.

    So the possible conversion sequences for (A) b, requiring a conversion sequence yielding B -> A, are:

    U1: B -> B [identity], B::operator A() [user-defined], A -> A [identity]
    U2: B -> B [identity], B::operator A &() [user-defined], A & -> A [rvalue-to-lvalue]
    

    Now, how do we rank standard conversion sequences? The place to look is table 12 in 13.3.3.1.1, which specifies that lvalue-to-rvalue conversion has the same rank (“Exact Match”) as identity conversion. So the two user-defined conversion sequences cannot be distinguished, and the program is ill-formed.


    Sidebar

    What’s the difference between 13.3.3 and 13.3.3.2 as regards ranking user-defined conversion sequences?

    13.3.3 allows the compiler to distinguish between different user-defined conversion operators; 13.3.3.2 allows the compiler to distinguish between different functions that each require a user-defined conversion in their arguments.

    So, in the code

    struct A {
        operator int();
        operator float();
    } a;
    void f(int);
    f(a);
    

    13.3.3 applies and A::operator int() is selected over A::operator float(); in the code

    struct A {
        operator int();
    } a;
    void f(int);
    void f(double);
    f(a);
    

    13.3.3.2 applies and void f(int) is selected over void f(double). However in the code

    struct A {
        operator int();
        operator float();
    } a;
    void f(int);
    void f(double);
    f(a);
    

    even though 13.3.3 prefers A::operator int() -> void f(int) over A::operator float() -> void f(int) and float -> double over int -> double, and 13.3.3.2 prefers int -> int over int -> double and float -> double over float -> int, there is no way to distinguish between the int -> int and float -> double conversion sequences (because they contain neither the same user-defined conversion operator nor the same overload of f), and so the code is ill-formed.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Given the following code: final class retVal { int photo_id; } Gson gson =
Given the following code. EventLoopScheduler scheduler = new EventLoopScheduler(ts => new Thread(ts)); BehaviorSubject<int> subject
Given the following code, is there a way I can call class A's version
Given the following code: int *a = NULL; a = calloc(1, sizeof(*a)); printf(%d\n, a);
The following code does not compile in gcc: namespace One{ class A{ }; };
I have following code: class TR_AgentInfo : public tuple< long long, //AgentId string, //AgentIp
The following code: #include <vector> struct S { int x, y; }; int main()
I know that following code gives compilation error : class A{ public : virtual
Given the following code: class Named { class /*Unnamed*/ { void Function(); } un;
The following code: #include <stdlib.h> #include <string.h> int main() { char *s = strdup(keep-alive);

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.