tags:

views:

176

answers:

4

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(); }
+1  A: 

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".

anon
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
@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.
anon
Neil, now I see your point.
shura
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
Wouldn't this example, if it worked, take two user-defined conversions? And don't we ever get only one?
sbi
@sbi That's true - I think D.Shawley's example is a better one.
anon
A: 

I guess that by keeping the conversion operator within the class you give the author of the class control of how it could be converted. As an implementer I would consider this an advantage.

daramarak
It doesn't give any extra control. I can (and probably should) simply write a ToBool() function to do the conversion.
anon
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
A: 

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
Um, wasn't this decided long before the standards committee ever met for the first time?
sbi
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
+1  A: 

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
+1 though I'd say `s/user-defined//`.
just somebody
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
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
@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