Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Templates...

Iniciado por BeRSeRKeR, 08 de Agosto de 2003, 04:49:01 PM

« anterior - próximo »

BeRSeRKeR

 Hola a todos.

Estoy intentando hacer una cosa con templates pero como no estoy demasiado experimentado con ellos pues no me sale lo que quiero hacer, así que  a ver si vosotros me podéis echar un cable.

Mirad este código:

using namespace std;

// Clase template
template<class DataType> class IFXVar
{
public:

string  m_strName;
DataType m_Value;
};

// Declaramos un map
map<string, IFXVar *> g_Vars;    // ESTO DEBE ESTAR MAL DECLARADO!

// Función template
template<class DataType> IFXVar<DataType> *RegisterVar(char *pszName, DataType val)
{
IFXVar<DataType> *pVar = new IFXVar<DataType>();

pVar->m_strName = string(pszName);
pVar->m_Value  = val;

g_Vars.insert(make_pair(pVar->m_strName, pVar));    // AQUI DA EL ERROR!

return pVar;
}

// Función principal
void main()
{
// Registramos una variable de tipo int
IFXVar<int> *pVar1 = RegisterVar("una_variable", 9);

// Registramos una variable de tipo string
IFXVar<string> *pVar2 = RegisterVar("otra_variable", string("Hola"));

// Liberamos memoria
delete pVar1;
delete pVar2;
}


Al principio declaro una clase template (IFXVar) que representa una variable. Esta tiene dos miembros, el nombre de la variable (m_strName) y el valor de la variable (m_Value). Como podéis ver, este miembro puede ser de cualquier tipo.

Despues declaro un map (g_Vars) en el que se irán almacenando todas las variables.

Finalmente declaramos una función template a través de la cual iremos registrando nuestras variables. Como podéis ver, a través del segundo parámetro de dicha función se le pasa el valor de la variable, el cual, una vez mas, puede ser de cualquier tipo.

Ahora bien, el problema se presenta en la declaración del map g_Vars ya que lo declaro de esta forma:

// Declaramos un map
map<string, IFXVar *> g_Vars;


cuando en realidad debería ser algo parecido a esto:

// Declaramos un map
map<string, IFXVar<???> *> g_Vars;


¿no?.

Ya que de otra forma, al hacer el make_pair en el método RegisterVar, me da un error de conversión de tipos:

c:\Developer\Microsoft Visual Studio .NET 2003\Vc7\include\utility(41): error C2440: 'initializing' : cannot convert from 'IFXVar<DataType> ' to 'IFXVar *' with [ DataType=int ]

El problema es qué de poner en lugar de "???" :D

Así que la pregunta es, cómo declarar el map de forma que pueda contener variables cuyo valor sea de cualquier tipo...

Por cierto, en el método RegisterVar, la forma de reservar memoria, ¿estaría bien? (funcionar, funciona) :):

IFXVar<DataType> *pVar = new IFXVar<DataType>();

Anyone, please? :)

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

ethernet

 Recuerda que los tipos de ls templates se resuelven en tiempo de compilacion, no de ejecucion. Tu problema no es facil, no lo estas orientando bien. Te recomiendo q te mires un cotd de hace unos meses de flipcode que es una clase any. Tb mirate boost::any (www.boost.org).

Por otro lado puedes hacer algo asi ->

class MyVar
{
std::string name;
void *Value;
//inventate la funcion de setear el valior y reservar la memoria
template T& GetValue(){ return *static_cast(Value); }
}

y despues para usarlo:

int var = o.GetValue(); //o es un objeto myvar

suerte con tus variables de configuracion

BeRSeRKeR

 Muchas gracias por la información, ethernet. Le echaré un vistazo a lo de boost::any aunque es posible que me tire por la opción que has mencionado.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

 He estado mirando el boost::any pero no hace exactamente lo que yo quería que era tener que ahorrarme la conversión de tipos cada vez que quisiera recoger el valor de la variable.

Así que, viendo que tendría que tener un método que me retornase el valor de la variable por cada tipo de dato requerido, no me voy a complicar la vida y por el momento la clase quedaría más o menos así:

class IFXVariable
{
public:

IFXVariable() {}
// DESCRIPCION: Constructor de la clase.
IFXVariable(string strName, string strValue) : m_strName(strName), m_strValue(strValue) {}
// DESCRIPCION: Constructor de la clase.

inline string GetName()         { return m_strName; }
// DESCRIPCION: Retorna el nombre de la variables.
inline string SetName(string strName)  { m_strName = strName; }
// DESCRIPCION: Especifica el nombre de la variable.

inline void  SetValue(string strValue) { m_strValue = strValue; }
// DESCRIPCION: Especifica el valor de la variable.

inline string GetString() { return m_strValue; }
// DESCRIPCION: Retorna el valor de la variable como un string.
inline int  GetInt()  { return atoi(m_strValue.c_str()); }
// DESCRIPCION: Retorna el valor de la variable como un int.
inline float GetFloat() { return (float)atof(m_strValue.c_str()); }
// DESCRIPCION: Retorna el valor de la variable como un float.
inline bool  GetBool()  { return GetInt() == 0 ? false : true; }
// DESCRIPCION: Retorna el valor de la variable como un bool.

private:
 
string m_strName;
string m_strValue;
};


De la forma que quería hacerlo yo, no hacía falta todo esto pero tenía el problema con el map que al parecer no tiene solución, así que de momento así se va a quedar. De todas formas si se os ocurre alguna forma más sencilla que ésta pues será bien recibida.

Por cierto, ¿por qué no se respetan las tabulaciones con el CODE?

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.