31

Why does C++ require that user-defined conversion operator can only be non-static member? Why is it not allowed to use standalone functions as for other unary operators? Something like this:

operator bool (const std::string& s) { return !s.empty(); }
einpoklum
  • 118,144
  • 57
  • 340
  • 684
shura
  • 694
  • 5
  • 9
  • 1
    This would be handy to convert between `std::string` and `QString`, which is acid in the face of my code's readability. – Gabriel Dec 21 '19 at 23:51

4 Answers4

11

The one reason I can think of is to prevent implicit conversions being applied to the thing being cast. In your example, if you said:

 bool( "foo" );

then "foo" would be implicitly converted to a string, which would then have the explicit bool conversion you provided applied to it.

This is not possible if the bool operator is a member function, as implicit conversions are not applied to *this. This greatly reduces the possibilities for ambiguity - ambiguities normally being seen as a "bad thing".

  • I don't understand your argument. The example you gave is not an implicit conversion. On the other hand the main reason for defining a conversion operator is to use implicit conversion. – shura Jan 31 '10 at 13:55
  • @shura Yes it is. "foo" is being implicitly converted to a string, which is then explicitly converted to a bool. I've updated my answer to clarify this. –  Jan 31 '10 at 13:58
  • 1
    To further explain the ambiguities, this could be treated as a conversion from pointer to `bool` though it would always result in `true` then. – D.Shawley Jan 31 '10 at 14:07
  • Wouldn't this example, if it worked, take two user-defined conversions? And don't we ever get only one? – sbi Jan 31 '10 at 14:19
  • @sbi That's true - I think D.Shawley's example is a better one. –  Jan 31 '10 at 14:24
  • 1
    But why is bool( "foo" ) == false a problem? This is exactly what the explicit conversion operator defined in the question means (if worked). – thor Jan 08 '14 at 14:34
  • 4
    There is a `explicit` keyword in **C++**. – Tomilov Anatoliy Oct 17 '14 at 06:42
0

By keeping the conversion operator within the class you give the author of the class control of how it could be converted (It prevents users from creating implicit conversions). As an implementer I would consider this an advantage, as implicit conversions does have its issues

There is a difference being able to pass one object as another, and having it to go through a conversion function. The former communicates that the object is of a given type, while the latter shows new readers that there is a difference between the two types and that a conversion is necessary.

Community
  • 1
  • 1
daramarak
  • 6,115
  • 1
  • 31
  • 50
  • 1
    It doesn't give any extra control. I can (and probably should) simply write a ToBool() function to do the conversion. –  Jan 31 '10 at 14:06
  • It does too :) Implicit conversion is something quite different than a ToBool(). If I could I would make std::string implicit convertible to a char*, but fortunately Stroustrup et al. knew better. – daramarak Jan 31 '10 at 21:38
-3

There's a group of operators that have to be overloaded as non-static member functions: assignment, subscripting, function call, class member access, conversion functions.

I guess the standard's committee or Stroustrup simply felt it might be just too confusing if it was allowed to inject these very special behaviors to classes from outside.


I suppose the best way to get the answer would be to e-mail the author.

UncleBens
  • 40,819
  • 6
  • 57
  • 90
  • Um, wasn't this decided long before the standards committee ever met for the first time? – sbi Jan 31 '10 at 19:22
  • Or perhaps Stroustrup felt this way. This is merely a speculation. What do these all have in common, so they all have to be members? I don't see any technical reason, why they should (OK, assignment would have a technical problem, since the compiler would otherwise synthesize it). – UncleBens Jan 31 '10 at 20:08
  • sad because converting "from std::string" to other things is a common desire – Erik Aronesty Apr 24 '15 at 20:10
-3

Implicit user-defined conversions are frowned upon anyway. Don't use them. Just pretend that they aren't there. Let alone thinking about newer ways to introduce them.

Anyway, I guess they aren't there because the way they are they can do enough unexpected things. Including a new header which introduces such a conversion for a class defined somewhere else might lead to even more confusing errors.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • So when C++0x allows using `explicit` with cast operators, does your argument still hold? I could envision some usefulness to freestanding cast operators that can be used only with `static_cast`. – jamesdlin Jan 31 '10 at 20:59
  • Not that I am a big fan of implicit user-defined conversioned. I wouldn't ever want to implicitly convert string to bool as in my example. But sometimes they are useful. Take std::string(const char*) for example. – shura Jan 31 '10 at 21:30
  • @shura: `std::string(const char*)` and `if(my_stream)` are the only two examples of useful implicit conversions that I see repeated over and over. (And I consider both debatable.) Has anyone ever come up with another useful example? – sbi Feb 07 '10 at 19:45
  • @sbi In Unreal C++ they have their own string class `FString` and `FText` on top of there being `const char*` and `std::string`. The only way to cast `std::string` to `FString` is to chain cast via `const char*` every time. Implicit cast here would be handy. – AustinWBryan Oct 29 '22 at 06:08
  • @AustinWBryan That would seem this way, but every time I thought so (I haven't done this in more than a decade), it turned out they caused problems. – sbi Nov 15 '22 at 21:10