views:

255

answers:

5

Okay so I have a class that has 'weak typing' I.E. it can store many different types defined as:

#include <string>

class myObject{
   public:
      bool isString;
      std::string strVal;

      bool isNumber;
      double numVal;

      bool isBoolean;
      bool boolVal;

      double operator= (const myObject &);
};

I would like to overload the assignment operator like this:

double myObject::operator= (const myObject &right){
   if(right.isNumber){
      return right.numVal;
   }else{
      // Arbitrary Throw.
      throw 5;
   }
}

So that I can do this:

int main(){
   myObject obj;
   obj.isNumber = true;
   obj.numVal = 17.5;
   //This is what I would like to do
   double number = obj;
}

But when I do that, I get:

error: cannot convert ‘myObject’ to ‘double’ in initialization 

At the assignment.

I have also tried:

int main(){
   myObject obj;
   obj.isNumber = true;
   obj.numVal = 17.5;
   //This is what I would like to do
   double number;
   number = obj;
}

To which I get:

error: cannot convert ‘myObject’ to ‘double’ in assignment

Is there something I am missing? or is it simply not possible to do a conversion like that by overloading operator=.

+13  A: 

Overloading operator= changes the behaviour when assigning to objects of your class type.

If you want to provide implicit conversion to other types you need to supply a conversion operator, e.g.

operator double() const
{
    if (!isNumber)
        throw something();
    return numVal;
}
Charles Bailey
And can that also be used with derived types like std::string?
zipcodeman
Yes, `operator std::string()` is a legal conversion operator.
Charles Bailey
Thank you, it worked like a charm!
zipcodeman
+2  A: 

for that to work, you need to implement a conversion operator from your object to something that can be converted into a double

jspcal
+7  A: 

What you really want are conversion operators.

operator double() const { return numVal; }
operator int() const { ...

That said, you'd probably like boost::variant.

Kornel Kisielewicz
A: 

To make a class assignable to a double, operator= must be defined differently.

double operator=(myclass&) is wrong.

What would work, is a friend operator= outside your class, which accepts double and myclass&.

Pavel Radzivilovsky
What you suggest cannot work. Assignment operators must be non-static member functions, then cannot be implemented as free friends.
Charles Bailey
+2  A: 

The return value of operator=() cannot be used as you have tried to demonstrate. If you think of the overloaded operator as a function in it's own right, it may make more sense.

For example:

int main() {
  myObject obj, obj2;
  obj.isNumber = true;
  obj.numVal = 17.5;
  obj2.operator=(obj); // equivalent to obj2 = obj
}

The reason number = obj; doesn't work is because you've defined myObject::operator=(), whereas number would be using double::operator=() (okay, technically there is no double::operator=() since it's a fundamental type and not a class...just work with me here).

An interesting note is that this function behaves like any other function in that the return value (return right.numval;) is ignored when it's not used. However, the return value can be assigned or used like the return value of any other function, so if you really wanted you could do something like this:

int main() {
  myObject obj, obj2;
  obj.isNumber = true;
  obj.numVal = 17.5;
  double number;
  // number = obj; still won't work.
  number = obj2 = obj; // equivalent to number = obj2.operator=(obj)
}

This is only so useful. As others have mentioned, you really want to look into conversion operators when trying to assign myObject objects to fundamental types.

goldPseudo
Thank you for the explanation, using conversion operators worked for me.
zipcodeman