Siempre hay soluciones.
En mi caso, yo primero declararía una clase que me permitiese manejar tipos de forma genérica (algo parecido a lo que echa de menos leosansan)
Código C++:
Ver originalclass Variant
{
public:
enum DataType
{
DTInt,
DTChar,
DTFloat
};
Variant( )
: _type( DTInt )
{
_data.intData = 0;
}
explicit Variant( int valor )
: _type( DTInt )
{
_data.intData = valor;
}
explicit Variant( char valor )
: _type( DTChar )
{
_data.charData = valor;
}
explicit Variant( float valor )
: _type( DTFloat )
{
_data.floatData = valor;
}
DataType Type( ) const
{ return _type; }
Variant& operator=( int valor )
{
_type = DTInt;
_data.intData = valor;
return *this;
}
Variant& operator=( char valor )
{
_type = DTChar;
_data.charData = valor;
return *this;
}
Variant& operator=( float valor )
{
_type = DTFloat;
_data.floatData = valor;
return *this;
}
int ToInt( ) const
{
int to_return = 0;
switch ( _type )
{
case DTInt:
to_return = _data.intData;
break;
case DTFloat:
to_return = static_cast< int >( _data.floatData );
break;
}
return to_return;
}
float ToFloat( ) const
{
float to_return = 0.0;
switch ( _type )
{
case DTFloat:
to_return = _data.floatData;
break;
case DTInt:
to_return = static_cast< float >( _data.intData );
break;
}
return to_return;
}
char ToChar( ) const
{
char to_return = 0;
switch ( _type )
{
case DTChar:
to_return = _data.charData;
break;
}
return to_return;
}
private:
union Data
{
int intData;
char charData;
float floatData;
};
Data _data;
DataType _type;
};
Se puede preparar para que admita más tipos, pero tampoco quería alargar demasiado el ejemplo.
Ahora necesitamos conectar esta clase con "cout" para poder imprimir el valor almacenado sin tener que andar haciendo cosas raras:
Código C++:
Ver originalstd::ostream& operator << ( std::ostream& stream, const Variant& variant )
{
switch ( variant.Type( ) )
{
case Variant::DTInt:
stream << variant.ToInt( );
break;
case Variant::DTChar:
stream << variant.ToChar( );
break;
case Variant::DTFloat:
stream << variant.ToFloat( );
break;
}
return stream;
}
Ahora, por sencillez, modifico ligeramente la estructura. Prefiero eso a tener una función externa, pero para gustos los colores:
Código C++:
Ver originalenum class Mascara
{
Campo1,
Campo2,
Campo3
};
struct datos
{
int dato1;
float dato2;
char dato3;
datos( )
: dato1( 3 ),
dato2( 3.85 ),
dato3( 'X' )
{
}
Variant Valor( Mascara mascara ) const
{
Variant to_return;
switch ( mascara )
{
case Mascara::Campo1:
to_return = dato1;
break;
case Mascara::Campo2:
to_return = dato2;
break;
case Mascara::Campo3:
to_return = dato3;
break;
}
return to_return;
}
};
Y ahora ya enlazamos todo esto con la aplicación:
Código C++:
Ver originalvoid ver(const std::vector< Mascara >& mascara, const datos&D);
int main()
{
datos D;
std::vector< Mascara > mascara { Mascara::Campo1, Mascara::Campo3 };
ver( mascara,D );
return 0;
}
void ver(const std::vector< Mascara >& mascara, const datos&D)
{
for ( auto it = mascara.begin( ); it != mascara.end( ); ++it )
{
std::cout << D.Valor( *it ) << " - ";
}
}
Et voilá. Todo funciona a pedir de boca XD