Channels ▼

Andrew Koenig

Dr. Dobb's Bloggers

A Language-Design Puzzle in Operator Overloading

May 09, 2012

My note last week about argument-dependent lookup reminded me of another problem from the early days of C++. The solution to this problem was a rule that few people even know exists — but without it, a lot of code would break.

Consider an expression such as a+b, where a and b are both class objects. The compiler treats this expression as if it might mean either a.operator+(b) or operator+(a, b), and considers all of the possibilities for each treatment as one big collection in deciding how to resolve the overloaded +.

Resolving an overloaded function call involves finding a single possibility that is strictly better than all the others. More specifically, it involves finding a possibility that is a better match than all the others in at least one argument, and no worse in any argument. For example:

 
             void f(std::string, int);
             void f(std::string, double);
 
             f("foo", 42);
 

Here, the call to f resolves to the first alternative, because int is a better match than double to the value 42, and the other argument (i.e., the first) requires a user-defined conversion in both cases. However, if instead we had written

 
             void g(std::string, int);
             void g(const char*, double);
 
             g("foo", 42);

the call would be ambiguous because the first g is a better match for the second argument and the second g is a better match for the first argument.

Now let's make the example a little more complicated:

 
             struct Thing {
                           void operator+(std::string);
             };
 
             void operator+(Thing&, const char*);
 
             Thing t;

and let's think about what happens to the expression t+"s". This expression might be interpreted as t.operator+("s") or as operator+(t, "s"), so the compiler must decide which of these two interpretations it prefers. In both cases, the left argument t has type Thing, so there is no reason to prefer either function to the other based on the first argument. However, the member operator+ has to convert its second argument to string, which means that the nonmember operator+ is a better match for the second argument. Therefore, the compiler will choose the nonmember.

Now let's complicate matters still further:

 
             struct Blob: public Thing { };
             Blob b;

and look at the expression b+"s". This is your chance to play language designer: See if you can figure out why the obvious way of interpreting this expression leads to trouble, and then see if you can figure out a language rule that offers a clean way to avoid this trouble.

I'll reveal the answer next week.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video