views:

127

answers:

2

Take the following class:

     class mytype {
        double num;
     public:
        mytype(int a) {
           num = sqrt(a);
        }
        void print() {
           cout << num;
        }
     }

Say there is a method which takes a mytype:

 void foo(mytype a) {
    a.print();
 }

Is it legal c++ (or is there a way to implement this) to call foo(4), which would (in theory) output 2? From what I can glean you can overload type casts from a user defined class, but not to. Can constructor do this in a standards-compliant manner (assuming, of course, the constructor is not explicit). Hopefully there is a way to in the end have this legal:

 int a;
 cin >> a;
 foo(a);

Note: this is quite obviously not the actual issue, but just an example for posting purposes. I can't just overload the function because of inheritance and other program-specific issues.

+2  A: 

Yes. Actually, this is the default action if the declaration of your class is #included.

To disallow this, your class constructor must be declared explicit. Note that only constructors that take one parameter (or constructors where every argument after the first has a default value) can use type coercion.

It is considered good practice to make all constructors explicit unless specifically desired. Note that even if your constructor is explicit, you can still do an anonymous conversion: foo(mytype(4));

rlbond
Thank you. This behavior is desired, in this case. Does this also work if foo took the superclass of mytype? Also, why must it be 4.0?
Robert Mason
I think rlbond didn't notice that the constructor mytype(int a) takes an int argument and the constructor internally converts it to double.
Windows programmer
@Windows programmer: you're correct. However, apparently this conversion is valid anyway for built-ins (but not for classes).
rlbond
+1  A: 

You can define conversions from native types as constructors like that, and conversions to native types such as operator int().

The only restrictions are that you cannot redefine conversion between native types, or (re)define operators operating only on native types, or define certain operators at all outside their operand class.

Potatoswatter