views:

97

answers:

3

If a class has a single argument constructor my understanding is it is implicitly convertible by the constructor to the type of the argument in appropriate contexts. Defining a conversion operator also makes a class convertible to another type. Questions

  • Does the conversion operator ever get called implicitly?
  • If both a single argument constructor and conversion operator with the same type are defined for a class does one have precedence over the other or is it ambiguous?
  • If you've decided that you want a class to be convertible to a given type, which approach is better or should you provide both?

Edit:

I see I didn't understand clearly the directionality and that the two perform conversions in the opposite directions. As a follow on

  • If you have control over two classes that you want to make convertible to and from each other is there a preferred way in terms of these two operations to accomplish this?
  • Is it possible mark the conversion operator as explicit?
+2  A: 

No, if a class has a single argument constructor is implicitly convertible from the type of its argument.

As for your other questions:

  • Does the cast operator ever get called implicitly?

Yes, whenever it is needed.

  • If both a single argument constructor and cast operator with the same type are defined for a class does one have precedence over the other or is it ambiguous?

I'm not too clear what you are asking, but if a conversion could go either way, it is ambiguous.

  • If you've decided that you want a class to be convertible to a given type, which approach is better or should you provide both?

You have to use a cast - constructors don't do this.

In general, if you don't want automatic conversions from a class to other types (and mostly you don't), it is better to provide named conversion functions (ToString, ToInt, ToX) which will never be called automatically by the compiler.

which leads on to your other two questions:

  • If you have control over two classes that you want to make convertible to and from each other is there a preferred way in terms of these two operations to accomplish this?

Yes, used a named function to perform at least one of the conversions. std::string does this - there is a conversion from a char * to string using a constructor, but the other way you need to use the named c_str() function.

  • Is it possible mark the conversion operator as explicit?

Unfortunately, no.

anon
+6  A: 

These two are opposites: non-explicit one-argument constructor allows for automatic type conversion to your class type from argument type. Conversion operator allows for implicit casting from your class type.

Common wisdom is to avoid both if not specifically required.

Nikolai N Fetissov
+1: *avoid both*
David Rodríguez - dribeas
Do you suggest std::string should not have an implicit conversion from const char *? That would make the class far harder to use.
anon
No, I'm not saying that. But I've seen many times people defining conversion operators on their own string classes, then being surprised that `+` is not always concatenation, but pointer arithmetic.
Nikolai N Fetissov
Surely the lesson is they should not have been writing their own string classes if they did not know what they were doing, rather than that all conversions should be banned?
anon
Neil, is *"if not specifically required"* qualifier not enough for you?
Nikolai N Fetissov
+2  A: 

if you have control over two classes that you want to make convertible to and from each other is there a preferred way in terms of these two operations to accomplish this?

I'd write a one-argument, explicit constructor.

I have seen too many really bad surprises when allowing implicit conversions, so I always disallow them. Writing f(A(b)) isn't much harder than writing f(b) and gives the compiler much more chance to give a meaningful error messages when the right f() isn't in scope.

sbi