1

In C++, the use of operator cast can lead to confusion to readers of your code due to it not being obvious that a function call is being invoked. That being said, I've seen its use being discouraged.

However, under what circumstances would using operator cast be appropriate and have value which exceeds any possible confusion it might lead to?

WilliamKF
  • 41,123
  • 68
  • 193
  • 295
  • I'm yet to see any good reason to do so. Operator casting always masks the fact a function is being run in the background and the infix notation is not worth it (and limits function naming). In C++ and similar languages, operator overloading should be avoided unless you know EXACTLY WHO IS GOING TO READ YOUR CODE (ie it's very bad in large/open source projects), and unless it SIMPLIFIES READABILITY CONSIDERABLY – Benjamin Gruenbaum Jun 06 '12 at 20:53
  • There is substantial difference between "operator cast" (defining a conversion operator between types) and "operator overloading" (defining, say, `operator+()` on a class). Which is this question about? – Mike C Jun 06 '12 at 21:00
  • 1
    You really have to judge this on a case-by-case basis by "smell". But of course each developer has different intuitions. Fortunately, you can tell when you've got it wrong, and fix it. If you find yourself debugging the cast operators, conversion constructors, or operators in some part of your code to figure out why some line is ambiguous, it's time to make things more explicit. When you find that half the text on a page of code is calls to get_ptr(x) or x.toString() so you can't readily see the actual logic, it's time to make it more implicit. – abarnert Jun 06 '12 at 21:57

2 Answers2

1

When the conversion is natural and has no side effects it can be useful. Nobody is going to argue that an automatic conversion from int to double is inappropriate for example, even if you can come up with a corner case that makes it confusing (and I'm not sure anybody can).

I've found the conversion from Microsoft's CString to const char * to be incredibly handy, even though I know others disagree. I wouldn't mind seeing a similar capability in std::string.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

Operator casts are very useful in a C++ idiom of wrapper objects. For example, suppose you have some copy-on-write implementation of a string class. You want your users to be able to index it naturally, like

const String s = "abc";
assert(s[0] == 'a');
// given
char String::operator[](int) const

So far, you'd think this would work. Yet what happens when someone wants to modify your string? Perhaps this will work, then?

String s = "abc";
s[0] = 'z';
assert(s[0] == 'z');
// given
char & String::operator[](int)

But this implementation gives a reference to a non-const character. So someone can always use that reference to modify the string. So, before it hands out the reference, it has to perform a copy of the string internally, so that other strings won't be modified. Thus it's not possible to use operator[] on non-const strings without forcing a copy. What to do?

Instead of returning a character reference, you can return a wrapper object with following interface:

class CharRef { public: operator char() const; CharRef & operator=(char); };

The char() conversion operator simply returns a copy of the character stored in the string. When you assign to the wrapper, though, the operator=(char) will force the string to perform an internal copy if the reference count is >1, and modify that copy instead.

The wrapper's implementation may, for example, hold the char and a pointer to the string (probably some subpart of the string's implementation).

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313