Re: ambiguous types: want automatic conversion
 
Hi,
"Markus Dehmann" <markus.dehmann@gmail.com> wrote in message 
news:1190327211.987359.227480@g4g2000hsf.googlegroups.com...
I think this is a question about automatic type conversion, but I
didn't find the answer after googling for these words ...
I have a class called Value (source see below) which can hold an int
or a string:
Value i(23);
Value s("blah");
Now I want an implicit conversion that automatically returns the
correct type, even in a context like this:
std::cout << i; // works
std::cout << s; // doesn't work: "Not an int" exception thrown
I think this should be feasible because the object knows what to
return (it was constructed with the certain type, although that's only
at runtime, not compile time ...).  Of course, I could have an
asString(), or an asInt() method in the class, but I want to avoid
that as it seems redundant. I also don't want to use external (non-
std) packages like boost.
Thanks for any help! The class I have so far is this:
 class Value {
   std::string stringValue;
   int intValue;
   bool isString;
   bool isInt;
 public:
   Value(std::string s) : isString(true), isInt(false),
stringValue(s) {}
   Value(int i) : isString(false), isInt(true), intValue(i) {}
   operator std::string (){
     if(!isString){throw std::runtime_error("Not a string");}
     return stringValue;
   }
   operator int (){
     if(!isInt){throw std::runtime_error("Not an int");}
     return intValue;
   }
 };
Yes that is possible. Just create a friend function like in my own variant 
class
//------------------------ Header----------------------
class UVar
{
friend std::ostream&  operator<<( std::ostream& Output,  const UVar& Var );
};
std::ostream&  operator<<( std::ostream& Output,  const UVar& Var );
//-----------------Source
std::ostream& operator<<( std::ostream& Output, const UVar& Var )
{
 Var.Print( Output );
 return Output;
}
void UVar::Print( ostream& Output ) const
{
 switch( Type )
 {
  case eNull:
   Output << "Null";
   break;
   case eLong:
   Output << Long;
   break;
  case eDouble:
   Output << Double;
   break;
  case eString:
   Output << *reinterpret_cast<const std::string*>( String );
   break;
  case eMap:;
   {
     Output << "Map : ";
      const map<UVar*,UVar*, UFindVar> Map1 = 
*reinterpret_cast<map<UVar*,UVar*, UFindVar> const *const>( Map );
    for( map<UVar*,UVar*, UFindVar>::const_iterator VarIter = Map1.begin(); 
VarIter != Map1.end(); ++VarIter )
    {
     Output << "Key(" << VarIter->first->type_name() << ") = " << 
*VarIter->first << ">  Value{ " << VarIter->second->type_name() << ") = <" 
<< *VarIter->second << ">";
    }
   }
   break;
  case eSRefPtr:
   Output << "Object Classname = " << ( 
*reinterpret_cast<MSRefPtr<ISerialize>const*>( SRefPtr ) ? 
(*reinterpret_cast<MSRefPtr<ISerialize>const*>( SRefPtr ) )->GetClassname() 
: string( "SRefPtr is null" ) );
   break;
  case eWRefPtr:
   Output << "Object Classname = " << ( 
*reinterpret_cast<MWRefPtr<ISerialize>const*>( WRefPtr ) ? 
(*reinterpret_cast<MWRefPtr<ISerialize>const*>( WRefPtr ) )->GetClassname() 
: string( "WRefPtr is null" ) );
   break;
  case eKey:
   Output << "MKey " << *reinterpret_cast<MKey const *>( KeyStroke );
   break;
  default:
   Channel << Chan1 << "Unknown type in UVar type = " << static_cast<int>( 
Type ) << End;
   throw CInfoException( "Unknown type" );
 }
}
Regards, Ron AF Greve
http://www.InformationSuperHighway.eu