Soledad Alborno | 1 Oct 2008 19:56
Picon

Re: aburridos? -> cadena de preguntas :D

mmm no me gusto el friend!!!

aca hay otra version

// CODIGO COMPLETO
#include <iostream>


template <class T>
class single_container
{
    T element;
public:

    single_container(const T &e)  :element(e){}

    template<class T2> single_container(single_container<T2>& t)
    {
        element = static_cast<T>(t);
    }

    single_container<T> & operator=(const T& t)
    {
        element=t;
        return *this;
    }

     template<class T2> single_container<T>& operator=(const single_container<T2>& t)
     {
               element = static_cast<T>(t);
               return *this;
     }

    operator T() const
    {
        return element;
    }
   

};

struct A{};
struct B
{
   B(){};
   B(const A& a){}
};

int main()
{
  /*standard convertion int <-> float*/
  single_container<int>   i(5);
  single_container<float> c(5.5);
  single_container<float> fl(i);
  single_container<int> iii(1);
  iii = 5;
  i=c;


  /*user define convertion A -> B*/
  A rr;
  B zz;
  single_container<A> r(rr);
  single_container<B> z(zz);
  single_container<B> x(r);
  z=r;

}

Marcelo Caro wrote:
Bien Hugo!!!
la única corrección a vuelo de pájaro es que el operador= quedaría:

 template<class T2> single_container<T>& operator=(const single_container<T2>& t)
       {
               element = t.element:
               return *this;
       }

Esperamos la siguiente pregunta!!!

Saludos.

2008/10/1 Hugo Villalba <hugo.villalba-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Bueno aca voy de nuevo. Con mucha ayuda de Marcelo puedo plantear la
siguiente solucion.

Le podemos agregar a la calse un operador de asignacion templetizado
el cual sera utilizado para construir instancias del tipo que estamos
pasando como parametro.

template<class T2> single_container<T2> operator=(const
single_container<T2>&)
{
       T2 x;
       return single_container<T2>(x);
}

Por ejemplo para el caso de la linea z=r sera equivalente a llamar a
single_container<B>::operator=(single_container<A> &) , donde B es T y
A es T2

Adicionalmente si queremos construir una nueva instancia de
single_container<B> usando como parametro de construccion un
single_container<A> deberiamos agregar un constructor que tome esos
parametros:

template <class T2> friend class single_container;    // Necesario
para permite que un single_container<A> acceda
single_container<B>.element

template<class T2> single_container(single_container<T2>& t)
{
       element = t.element;  // Es posible gracias al friend de arriba ya
que ambos templates son de distinto tipo
}


// CODIGO COMPLETO
#include <iostream>

using namespace std;
#include <iostream>

template <class T>
class single_container
{
       T element;
public:

       single_container(const T &e)  :element(e){}

   template <class T2> friend class single_container;

       template<class T2> single_container(single_container<T2>& t)
       {
               element = t.element;
       }

       single_container<T> & operator=(const T& t)
       {
               element=t;
               return *this;
       }

       template<class T2> single_container<T2> operator=(const
single_container<T2>&)
       {
               T2 x;
               return single_container<T2>(x);
       }

       operator T() const
       {
               return element;
       }
};

struct A{};
struct B
{
  B(){};
  B(const A& a){}
};

int main()
{
 /*standard convertion int <-> float*/
 single_container<int>   i(5);
 single_container<float> c(5.5);
 single_container<float> fl(i);
 single_container<int> iii(1);
 iii = 5;
 i=c;


 /*user define convertion A -> B*/
 A rr;
 B zz;
 single_container<A> r(rr);
 single_container<B> z(zz);
 single_container<B> x(r);
 z=r;
}


Saludos

Hugo




On Sep 30, 10:48 pm, M <at> rC€ <marcec...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Vas por buen camino, pero a mi no me compila la modificación (en
> visual c++ si, pero en gcc y comeau no).
>
> Generalmente yo evito los operadores de conversión (sobretodo para
> convertir entre clases, ya que hay otra alternativa (ayudita)) por que
> pueden provocar bastantes ambigüedades.
>
> Es interesante la ambiguedad que ocurre:
>
> single_container<int>   i(5);
> single_container<float> fl(i);  -> ambiguo.
>
> 1)se puede interpretar como: convertir "i" a single_container<float>
> ( con el operador nuevo) y utilizar el constructor por copia de
> single_container<float>.
> 2)se puede interpretar como:  aplicar sobre "i" el operadotor
> "operator int()" y luego se convierte en "float" despues utilizar el
> constructor single_container<float>::.single_container(const float&).
>
> Algo parecido pasa con el operador =, resulta ambiguo.
>
> La modificacion si funciona para las clases A y B sin ambiguedad ya
> que supongamos:
>
>   single_container<A> r(rr);
>   single_container<B> z(r);  -> No resulta ambiguo.
>
> 1)La unica  opcion es: convertir "r" a single_container<B> y luego
> aplicar el operador por copia de single_container<B>,
> 2)La otra opcion no es valida ya que requeriria dos converciones "user
> defined": aplicar sobre "r" "operator A() convertir de A a B y luego
> usar el constructor por copia de single_container<B>.
>
> Saludos.
>
> Marcelo.
>
> On Sep 30, 9:24 pm, Hugo Villalba <hugo.villa...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > Bueno aqui va la respuesta (Agradezco al amigo Bjarne Pg 349 / 350)
> > Lo que le esta faltando al template es un "Template Conversion".
>
> > template<class T2> operator single_container<T2>()  {
> >         T2 t;
> >         return single_container<T2>(t);
>
> > }
>
> > Si agregamos este "template conversion" cuando se ejecute la linea z=r
> > tratara de convertir implicitamente r en una instancia de tipo
> > single_container<B>
> > La clase queda de la siguiente forma:
>
> > // codigo completo
> > template <class T> class single_container
> > {
> >         T element;
>
> > public:
> >         single_container(const T &e) :element(e){}
>
> >         single_container<T> & operator=(const T& t){
> >                 element=t;
> >                 return *this;
> >         }
>
> >         operator T() const{
> >                 return element;
> >         }
>
> >         template<class T2> operator single_container<T2>()  {
> >                         T2 t;
> >                 return single_container<T2>(t);
> >         }
>
> > };
>
> > Es correcto ?
> > Saludos
>
> > Hugo
>
> > On 30 sep, 10:05, "Marcelo Caro" <marcec...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > > tambien falto el return *this;  :)
>
> > > single_container<T> & operator=(const T& t)
> > >    { element=t; return *this:}
> > > ;)
>
> > > 2008/9/30 Marcelo Caro <marcec...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> > > > definitivamente si.
> > > > :)
>
> > > > 2008/9/30 Soledad Alborno <soledad.albo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> > > > me parece que tu operator= en single_container deberia ser:
>
> > > >>    single_container<T> & operator=(const T& t)
> > > >>    { element=t; }
> > > >> ;)
>
> > > >> Ahora si... cual seria la respuesta ?  (a ver quien mas se prende!!! )
>
> > > >> Sole
>
> > > >> 2008/9/30 M <at> rC€ <marcec...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> > > >>> Bueno, una pregunta fácil para calentar motores.
>
> > > >>> Tengo un template single_container<T> que lo único que hace
> > > >>> es contener un elemento de tipo T.
>
> > > >>> Código:
>
> > > >>> template <class T>
> > > >>> class single_container
> > > >>> {
> > > >>>    T element;
> > > >>>  public:
> > > >>>    single_container(const T &e)
> > > >>>        :element(e){}
> > > >>>    single_container& operator=(const T& t)
> > > >>>    { element=t; }
> > > >>>    operator T() const
> > > >>>    {  return element; }
> > > >>>    //...
> > > >>> };
>
> > > >>> Pregunta: Como modifico el template para que
> > > >>> si existe una conversión standard de A a B entonces
> > > >>> exista una conversion de single_container<A> a single_container<B> ?
>
> > > >>> Ayuda: Después de la modificación,
> > > >>> el siguiente código debería compilar.
>
> > > >>> struct A{};
> > > >>> struct B{
> > > >>>    B(){};
> > > >>>    B(const A& a){}
> > > >>>    };
>
> > > >>> int main()
> > > >>> {
> > > >>>   /*standard convertion int <-> float*/
> > > >>>   single_container<int>   i(5);
> > > >>>   single_container<float> c(5.5);
> > > >>>   single_container<float> fl(i);
> > > >>>   i=c;
>
> > > >>>   /*user define convertion A -> B*/
> > > >>>   A rr;
> > > >>>   B zz;
> > > >>>   single_container<A> r(rr);
> > > >>>   single_container<B> z(zz);
> > > >>>   z=r;
> > > >>> }
>
> > > >>> Saludos.
> > > >>> Marcelo.
>
> > > >>> On 30 sep, 09:03, "Soledad Alborno" <soledad.albo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > > >>> > Excelente :) q venga la segunda nomas!
> > > >>> > Saluditos
> > > >>> > Sole
>
> > > >>> > 2008/9/29 M <at> rC€ <marcec... <at> gmail.com>
>
> > > >>> > > Según el standard sección 15.1 seria algo así:
>
> > > >>> > > "Ex constructor - "   throw Ex() -> se construye en el throw (queda
> > > >>> en
> > > >>> > > un lugar temporal).
> > > >>> > >                             catch ( Ex &e1 ) -> en el primer catch,
> > > >>> > > al cachear por referencia solo toma una referencia a la variable
> > > >>> > > temporal.
> > > >>> > > "catch e1 - "        cout << "catch e1 - " ;
> > > >>> > >                          throw; -> se relanza el temporal, por eso no
> > > >>> > > hay creación de objeto.
> > > >>> > > "Ex copy - "        catch ( Ex e1 ) ->  se atrapa y se construye e1
> > > >>> > > por copia.
> > > >>> > > "catch e2- "         cout << "catch e2- ";
> > > >>> > > "destructor - "      se destruye e1  (ojo: el segundo en el código,
> > > >>> es
> > > >>> > > decir, el que es por copia ya que ambos se llaman e1).
> > > >>> > > "destructor - "      se destruye el temporal.
>
> > > >>> > > Confirma si está bien y hago la siguiente pregunta. (para ir
> > > >>> > > prolijamente y no mezclar)
>
> > > >>> > > Saludos.
> > > >>> > > Marcelo.
>
> > > >>> > > On Sep 29, 4:16 pm, "Soledad Alborno" <soledad.albo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > > >>> > > wrote:
> > > >>> > > > Hey!
>
> > > >>> > > > Quien se prende a una cadena de preguntitas?
> > > >>> > > > La onda es esta: posteo una pregunta,  facil facil, el que la
> > > >>> responda
> > > >>> > > > deberá postear la siguiente :D
>
> > > >>> > > > ahi va:
>
> > > >>> > > > Cual es la salida del codigo que esta aca abajo? no vale
> > > >>> ejecutarlo!!!
> > > >>> > > > (RAPIDO muevan las neuronas y los dedos :) )
>
> > > >>> > > > class Ex {
>
> > > >>> > > > public:
>
> > > >>> > > > Ex(){ cout << "Ex constructor - "; }
>
> > > >>> > > > Ex( const Ex &) {cout << "Ex copy - " ; }
>
> > > >>> > > > ~Ex() { cout << "destructor - "; }
>
> > > >>> > > > };
>
> > > >>> > > > int main() {
>
> > > >>> > > > try {
>
> > > >>> > > >      try {
>
> > > >>> > > >          throw Ex();
>
> > > >>> > > >      } catch ( Ex &e1 ) {
>
> > > >>> > > >           cout << "catch e1 - " ;
>
> > > >>> > > >           throw;
>
> > > >>> > > >      }
>
> > > >>> > > > } catch ( Ex e1 ) {
>
> > > >>> > > >      cout << "catch e2- ";
>
> > > >>> > > > }
> > > >>> > > > }
>
> > > >>> > > > saludos
>
> > > >>> > > > Sole
>
> > > >>> > > > PD: si yo estoy un poquito aburrida leyendo Jingle ( si si los
> > > >>> tiempos
> > > >>> > > > vuelan, ya cambiamos H323 por SIP hoy SIP por Jingle )
>
> > > > --
> > > >           Marcelo
>
> > > --
> > >           Marcelo- Ocultar texto de la cita -
>
> > > - Mostrar texto de la cita -




--
          Marcelo



--~--~---------~--~----~------------~-------~--~----~
¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido este mesaje por error.
En caso de duda visita "http://groups.google.com/group/cppba"
-~----------~----~----~----~------~----~------~--~---


Gmane