C++ tagfüggvény paramétertípusa még nem definiált osztályban levő typedef
2021-10-20T13:46:31+02:00
2021-10-20T20:43:56+02:00
2022-08-19T02:31:17+02:00
x00
Üdvözletem, a szakértők segítségét kérném:

Az expr nevű osztályban csak egy mutató van, az exprdata-ban vannak a tényleges adatok és a hivatkozásszámláló. Először az exprdata van definiálva, majd az expr. Az exprdata tagfüggvényének paramétertípusa az expr-től is függő bejáró, mely hibát ad, hogy még nem definiált osztályt használok. Már a paramétertípus is hibát ad: a tagfüggvény prototípusa, így azt is az expr mögé kellett tennem, így nem lehetett tagfüggvény. Mindegy, hogy kiírom-e hogy "typename" vagy nem. Valahogy megoldható hogy tagfüggvény maradjon? Visual C++ 2019 16.11.5-öt használok. Kódrészletek (remélem fordítható, csak annyit írtam ki hogy az legyen, nem az egészet):

// AVL-elem lenne, most hogy fordítható legyen, ennyi elég: template<class t> class _single_inheritance TEAvl { public: t member; // itt jelzi a fordító, hogy nem definiált osztályt használok class iterator {}; // ebben nyilván van t * is }; class _single_inheritance expr; class _single_inheritance exprdata { // Mezők, tagfüggvények, konstruktor, destruktor, friend-ek // Már a prototípus hibát ad, mindegy hogy ott van-e a typename void CopySide(typename TEAvl<expr>::iterator &); }; // csak exprdata* és tagfüggvények, konstruktor, destruktor, friend-ek class expr {};
Köszönöm.
Mutasd a teljes hozzászólást!
Bár szakértő nem vagyok, leírom azért az ötleteimet, ártani csak nem árt

Első kerülő megoldás: Vedd ki az iterátort saját top-level típusba:

template<class t> class TEAv1_iterator {} template<class t> class TEAv1 { t member; // ízlés szerint, ha szükség van a TEAv1<t>::iterator formában is az elérésre typedef TEAv1_iterator<t> iterator; } class expr; class exprdata { void CopySide(TEAv1_iterator<expr> &); }; class expr {};
Második kerülő megoldás: legyen az "exprdata" is template, és akkor csak az első felhasználás helyén példányosodik, ahol remélhetőleg az expr implementációja ismert:

template<class t> exprdata { void CopySide(typename TEAv1<t>::iterator &); }
Mutasd a teljes hozzászólást!

  • Nem definiált osztályt ne akarj beilleszteni, csak rá mutató pointert.

    class masik; class egyik { masik *pmasik };
    Mutasd a teljes hozzászólást!
  • t member: itt így kell maradnia. Itt jelzi a hibát, és a paramétertípus miatt akarja példányosítani:
    void CopySide(typename TEAvl<expr>::iterator &);

    Kipróbáltam, hogy a & helyett *-ot írok, vagyis hivatkozás helyett mutató, ugyanúgy nem fogadja el.

    Az a probléma, hogy amikor a fordító meglátja hogy TEAvl<expr>::iterator, akkor egyből példányosítani akarja, holott erre is csak referencia vagy mutató van. Gondolom a C++ nyelv nem engedi meg a ::iterator elérését példányosítás nélkül. Valami kerülő megoldás?

    Azt én is tudom, hogy ha nem definiált osztályt lehetne beilleszteni, akkor rekurzív típusokat lehetne létrehozni, végtelen méretűt, mert tartalmazná önmagát. Én a typedef-ét szeretném elérni paramétertípusként, rá mutatót.
    Mutasd a teljes hozzászólást!
  • Akkor, gondolom, referenciát sem akarsz a definiálatlan osztályra.

    class nincs; class egyik { nincs &rnincs; egyik(nincs &par): rnincs(par) {} };
    Mutasd a teljes hozzászólást!
  • Valóban nem létfontosságú, jó helyette a mutató.
    Mutasd a teljes hozzászólást!
  • Bár szakértő nem vagyok, leírom azért az ötleteimet, ártani csak nem árt

    Első kerülő megoldás: Vedd ki az iterátort saját top-level típusba:

    template<class t> class TEAv1_iterator {} template<class t> class TEAv1 { t member; // ízlés szerint, ha szükség van a TEAv1<t>::iterator formában is az elérésre typedef TEAv1_iterator<t> iterator; } class expr; class exprdata { void CopySide(TEAv1_iterator<expr> &); }; class expr {};
    Második kerülő megoldás: legyen az "exprdata" is template, és akkor csak az első felhasználás helyén példányosodik, ahol remélhetőleg az expr implementációja ismert:

    template<class t> exprdata { void CopySide(typename TEAv1<t>::iterator &); }
    Mutasd a teljes hozzászólást!
abcd