[C con Clase] Un error con (¿...?) en GCC y no en Visual Studio (Parte III)

Gilberto Cuba Ricardo gilbert en ucp.ho.rimed.cu
Sab Jul 10 19:30:48 CEST 2010


Hola Davidson,

Steven Davidson escribió:

> Hola Gilberto,

> ¿Estás seguro que quieres estos parámetros? Si es correcto, entonces es
> posible que quieras definir la plantilla 'definition' para cualesquier
> parámetros. De lo contrario, esta estructura debe ser: 
> 'definition<MyFirstClass,MyFirstClass>' o 
> 'definition<MyHeritClass,MyHeritClass>'.

Lo que no entiendo de esta parte es, cómo es que MSVC puede resolver a
"definition" como "definition<MyHeritClass,MyHeritClass>" y no así GCC,
porque como usted bien dice a continuación que esta es una
especialización parcial que ha sido definida a partir de
"struct definition<MyHeritClass, T>" por lo que sigo sin entender cómo
es que no puede resolver a T como "MyHeritClass" o si lo resuelve
bien, cual es el problema de la declaración estática de
"definition<MyHeritClass,MyHeritClass>" para luego retornar su
dirección de memoria.

> Esto significa que se retornará la dirección de memoria del objeto 
> estático de la estructura 'definition<MyHeritClass,MyHeritClass>'. Esta
> clase fue generada a partir de la especialización parcial que 
> escribiste: 'struct definition<MyHeritClass, T>', donde T='MyHeritClass'.

Ajá, esto lo entiendo y reafirma lo anterior.

>>       public:
>>         virtual void method_01() {}
>>         virtual void method_02() {}
>>       };
>> 
>> 
>>   template<typename T>
>>   struct definition<MyFirstClass, T> : public vmt_definition<T>
>>     {
>>       definition()
>>         {
>> [3]          def_method( "method1", &MyFirstClass::method01 );

> Esto implica que los parámetros de 'def_method' serán RT='void' y 
> T='MyFirstClass'. Esto también implica que invocas 
> 'vmt_definition<MyFirstClass>::def_method()'. Por consiguiente, esta 
> plantilla debe ser 'definition<MyFirstClass, MyFirstClass>'. Sin 
> embargo, debes ser explícito, ya que 'def_method()' no fue definida en
> este ámbito sino en otro. Deberías escribir:

> this->vmt_definition<T>::def_method( "method1", &MyFirstClass::method01 );

¿Y no es lo mismo en este ámbito

- vmt_definition<T>::def_method( "method1", &MyFirstClass::method01 );

que

- this->vmt_definition<T>::def_method( "method1", &MyFirstClass::method01 );
? :-O

> Ten presente que los punteros a los miembros de una clase no siguen las
> reglas de herencia, sino de ámbito. Por lo tanto, el puntero a una 
> función miembro de 'MyFirstClass' no es "transferible" a un puntero de
> otra clase.

Aquí me perdí con esto y por eso la pregunta anterior.

> El problema que estás teniendo es que instancias previamente un objeto
> de la clase 'definition<MyFirstClass, MyHeritClass>'. Esto no concuerda
> con lo que hemos mencionado antes y por tanto no encuentra una 
> definición de 'def_method()' adecuada.

> Podría escribir:

> vmt_definition<MyHeritClass>::def_method( std::string("method1"), 
> &MyHeritClass::method_01 );

Aquí igual me pierdo porque esto es lo que está escrito en el mensaje
anterior que he dicho que aplico como cambio en al segunda
especialización parcial de "definition", y que me sigue devolviendo
error en [3]; sólo que creo que no comenté sobre este que es:

|error: no matching function for call to `definition<MyFirstClass, MyHeritClass>::def_method(const char[8], void (MyFirstClass::*)())'|

y haciendo la salvedad del "std::string("method1")" que para el caso
es lo mismo, aunque con el temor a equivocarme. ;-)

> Pero seguramente esto no es lo que querías hacer.

Si con lo anterior se referería a incluirlo dentro de la primera
especialización parcial de "definition", pues entonces la solución
al problema no satisface lo que quería, porque supongamos que tenemos
lo siguiente también dentro del mismo código anterior:

    //...
    class MyOtherHeritClass : public MyFirstClass
      {
      public:
        virtual IClassTypeInfo* get_typeInfo() { return resolve_definition<MyOtherHeritClass>(); }
      public:
        virtual void method_X_01() {}
        virtual void method_X_02() {}
      };

    //...
    //que es una clase por el estilo a MyHeritClass y entonces su
    //especialización parcial heredada de la primera.

    template<typename T>
    struct definition<MyOtherHeritClass, T> : public definition<MyFirstClass, T>
      {
        definition()
          {
            // - esta línea asumiéndola con la recomendación siguiente..
            definition<MyFirstClass, T>::def_method( "method_01", &MyOtherHeritClass::method_X_01 );
          }
      };

Entonces tendría que brindar esa misma funcionalidad en la primera
especialización parcial de "definition", lo cual no es conveniente.

>>         }
>>     };
>> 
>>   template<typename T>
>>   struct definition<MyHeritClass, T> : public definition<MyFirstClass, T>
>>     {
>>       definition()
>> [4]        {
>> [5]          def_method( "method_01", &MyHeritClass::method_01 );

> Aquí tienes algo parecido al caso anterior. Puedes escribir:

> definition<MyFirstClass, T>::def_method( "method_01", 
> &MyHeritClass::method_01 );

Ajá, este me parece más seguro que el otro mio.

> Espero haber aclarado algo de este tema.

Por lo menos lo intentamos. Gracias de todas formas, aunque no hayamos
logrado salir del bache. :-)

> Steven

-- 
Salu2,
 Gilbert





Más información sobre la lista de distribución Cconclase