Sehe durch meine Template-Konstruktionen nicht mehr durch ...



  • Hi,

    folgende zwei klassen existieren:

    template<class X,class Y> P {
      P(X x, Y y);
    }
    
    template<class X,class Y> F {
      ...
    }
    

    angewendet in einer anderen Klasse:

    template<class S,class CS> D { 
      ...
      // CS_temp und f haben den richtigen Typ
      P<CS, F<S, CS> > tmp_p(CS_temp,f);
    

    Wird die Klasse D nun als D<P<double, int>, P<double, SimpleProbability<int> > > genutzt, komme ich irgendwann zu folgendem Fehler (ausgeloest in obiger P<CS, ... > temp_p(...) Zeile:

    ../P.h: In constructor ‘P<TYPE_LEFT, TYPE_RIGHT>::P(TYPE_LEFT, TYPE_RIGHT)
    [with TYPE_LEFT = P<double, SimpleProbability<int> >, TYPE_RIGHT = F<P<double, int>, P<double, SimpleProbability<int> > >]’:

    ../D.h:36: instantiated from ‘COMPLEX_STATE_TYPE D<SIMPLE_TYPE, COMPLEX_TYPE>::A(SIMPLE_TYPE) [with SIMPLE_TYPE = P<double, int>, COMPLEX_TYPE = P<double, SimpleProbability<int> >]’
    ...
    instantiated from here
    ...

    ../P.h:17: error: no matching function for call to ‘P<double, SimpleProbability<int> >::P()’

    Das problem ist also das es keinen Default-Konstruktor fuer P gibt (wuerde auch wenig Sinn machen). Wohl aber den oben angegebenen Input-Konstruktor. Warum braucht man in "P<CS, F<S, CS> > tmp_p(CS_temp,f)" aber einen P() - Konstruktor? Und wie kann man das umgehen?

    Gruesse Frager. 🙂



  • Frager schrieb:

    ...

    template<class X,class Y> P {
      P(X x, Y y);
    }
    
    template<class X,class Y> F {
      ...
    }
    
    template<class S,class CS> D { 
      ...
      // CS_temp und f haben den richtigen Typ
      P<CS, F<S, CS> > tmp_p(CS_temp,f);
    

    ...

    Das eine oder andere "class" würde nicht nur uns, sondern auch dem Compiler den Durchblick erleichtern. 😉
    - ach ja: Da, wo Du derzeit "class" schreibst, ist inzwischen "typename" angesagt.

    Gruß,

    Simon2.



  • Hi,

    erstens:
    was ist eigentlich der Unterschied zwischen template<class T> und template<typename T> ... ?

    zweitens:
    das problem nochmal uebersichtlicher und viel einfacher:

    template<typename X,typename Y> 
    class P {
      P(X x, Y y);
    }
    

    angewendet woanders:

    P<double,int> p(0,0);
    
    P<P<double,int>, P<double,int> > pp(p,p);
    

    fuehrt zu:

    .../P.h: In constructor ‘P<TYPE_LEFT, TYPE_RIGHT>::P(TYPE_LEFT, TYPE_RIGHT) [with TYPE_LEFT = P<double, int>, TYPE_RIGHT = P<double, int>]’:

    main.cpp:12: instantiated from here

    .../P.h:17: error: no matching function for call to ‘P<double, int>::P()’

    Warum wird hier nach einem P::P() Konstruktor verlangt?? Wie kann man diese umgehen?

    Gruesse Frager. :)[/quote]



  • Hi,

    fand soeben herraus, dass

    P<P<double,int>, P<double,int> > pp(P<double,int> (p), P<double,int> (p));
    

    funktioniert ... aber wieso muss man den copy konstruktor nochmal explizit aufrufen? 😕

    Gruesse Frager. 🙂



  • Frager schrieb:

    Hi,

    erstens:
    was ist eigentlich der Unterschied zwischen template<class T> und template<typename T> ... ?

    typename sieht schöner aus 😃 (syntaktisch ist beides gleichwertig)

    zweitens:
    Warum wird hier nach einem P::P() Konstruktor verlangt?? Wie kann man diese umgehen?

    Um diese Frage zu beantworten, müssten wir die Definition des P-Ctor's sehen.

    Ich tippe mal spontan darauf, daß du im Ctor-Rumpf die Elemente deines Paares mit den übergebenen Parametern füllst. Das bedeutet, daß der Compiler diese Elemente zunächst mit dem Default-Ctor initialisieren und anschließend einen neuen Wert zuweisen muß. Die Lösung des Problems heißt "Initialisierungsliste":

    template<typename X,typename Y>
    class P
    {
      X val1;
      y val2;
    public:
      P(X x,Y y) : val1(x), val2(y) {}
    };
    


  • CStoll schrieb:

    Ich tippe mal spontan darauf, daß du im Ctor-Rumpf die Elemente deines Paares mit den übergebenen Parametern füllst. Das bedeutet, daß der Compiler diese Elemente zunächst mit dem Default-Ctor initialisieren und anschließend einen neuen Wert zuweisen muß. Die Lösung des Problems heißt "Initialisierungsliste":

    template<typename X,typename Y>
    class P
    {
      X val1;
      y val2;
    public:
      P(X x,Y y) : val1(x), val2(y) {}
    };
    

    Yipp, so gehts ... 😮
    CStoll, du bist gut 😃

    Vielen Dank,
    Frager


Anmelden zum Antworten