Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precedence of overloaded cast operators

In the code below, I would expect to get a compiler error if more than one cast operator is defined because of the ambiguity.

#include <iostream>
#include <sstream>

struct A
{
    operator const char*() { return "hello world\n"; }
    operator float()       { return 123.0F; }
    //operator int()         { return 49; }
};

int main()
{
    A a;
    std::stringstream ss;
    ss << a;
    std::cout << ss.str();
    return 0;
}

Instead, as long as only one numeric cast operator is defined then it compiles with no errors, no warnings, and the numeric cast is used in preference to the operator const char *(). The order of the declared operators makes no difference.

However if operator int() and operator float() are both defined then I get what I expected from the start:

'operator <<' is ambiguous

Are there precedence rules for casts, or why does the compiler choose the numeric cast by default? I do understand that I should explicitly state which cast I mean, but my question is on the default choice the compiler makes.


Edit: Using compiler MSVC 2010
like image 897
acraig5075 Avatar asked Jan 16 '13 14:01

acraig5075


People also ask

Can operator overloading change the precedence?

Overloading an operator cannot change its precedence.

Which operator has the highest precedence?

The logical-AND operator ( && ) has higher precedence than the logical-OR operator ( || ), so q && r is grouped as an operand. Since the logical operators guarantee evaluation of operands from left to right, q && r is evaluated before s-- .

What are the precedence of operators?

The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3 , the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary.

Which of the following operator has more precedence A () B ++ C * D >=?

Explanation: Operator ++ has the highest precedence than / , * and +.


1 Answers

Conversions are ranked according to § 13.3.3.1 of the C++ Standard. In particular, user-defined conversion sequences pertinent to your example are regulated by § 13.3.3.1.2/1:

"A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-defined conversion (12.3) followed by a second standard conversion sequence. [...] If the user-defined conversion is specified by a conversion function (12.3.2), the initial standard conversion sequence converts the source type to the implicit object parameter of the conversion function."

All conversions sequences here involve:

  1. a fictitious conversion to the source type of the implicit object parameter of the conversion function;
  2. a user-defined conversion;
  3. an identity conversion to the input type of operator <<.

These conversion sequences all have the same rank. Thus, the call should be ambiguous. If it is not, for me it is a compiler bug.

like image 141
Andy Prowl Avatar answered Oct 16 '22 21:10

Andy Prowl