Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoking conversion operators

Tags:

c++

operators

What's the reason for the following behavior?

class BoolWrapper
{
public:
    BoolWrapper(bool value) : value(value) {}

    operator bool() const { return value; }
    operator int() const { return (int) value; }

private:
    bool value;
};


BoolWrapper bw(true);

if (bw) { ... }            // invokes operator bool()
if (bw == true) { ... }    // invokes operator int() -- why?

Is this behavior expected? (Using GCC 4.7.2.)

like image 395
peter.slizik Avatar asked Nov 06 '12 16:11

peter.slizik


People also ask

How do you call a conversion operator?

You can call it directly (explicitly) like this: Bob b; std::string s = b. operator std::string();

What is a conversion operator?

A conversion operator, in C#, is an operator that is used to declare a conversion on a user-defined type so that an object of that type can be converted to or from another user-defined type or basic type. The two different types of user-defined conversions include implicit and explicit conversions.

What is the C++ conversion operator?

Conversion Operators in C++ Sometimes, it is required to convert one concrete type to another concrete type or primitive type implicitly. Conversion operators play an important role in such situations. It is similar to the operator overloading function in class.

What is the return type of the conversion operator?

1. What is the return type of the conversion operator? Explanation: Conversion operator doesn't have any return type not even void.


2 Answers

Your expectations are based on your belief that the language already knows how to compare two bool values. In reality it doesn't, however surprising it might sound. More precisely, the language "does not know" how to do it directly.

At the conceptual level, C++ does not have a dedicated built-in equality comparison operator for bool vs. bool comparisons. Even when you write true == false in your code, it is really interpreted by the language as (int) true == (int) false. The implicit conversion to int is introduced by the rules of usual arithmetic conversions and int vs. int comparison is used afterwards.

The most immediate built-in operator that can compare two bool values is the one for int vs. int comparison. This is the operator the compiler is trying to use in your case as well. The very same operator will be used for char vs. char and short vs. short comparisons.

In other words, the only way the compiler can use your bool conversion operator in the bw == true expression would be to do

(int)(bool) bw == (int) true

This is certainly less "optimal" than the direct

(int) bw == (int) true

This is the logic that drives the language to select the latter variant.

like image 172
AnT Avatar answered Nov 11 '22 22:11

AnT


From 5/9:

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

[Some floating point items that don't matter.]

Otherwise, the integral promotions (4.5) shall be performed on both operands.

And from 3.9.1/6 we see that bool is eligible for integral promotion:

Values of type bool are either true or false.42) [Note: there are no signed, unsigned, short, or long bool types or values. ] As described below, bool values behave as integral types. Values of type bool participate in integral promotions (4.5).

like image 38
Mark B Avatar answered Nov 11 '22 21:11

Mark B