CRTP ősosztály miatt miért nem elég a _single_inheritance Visual C++-ban?

CRTP ősosztály miatt miért nem elég a _single_inheritance Visual C++-ban?
2021-11-26T22:25:38+01:00
2021-11-27T21:38:15+01:00
2022-10-15T21:20:41+02:00
x00
Tisztelt szakértők!

template<class t> class CRTP { t *p; }; class _single_inheritance base: CRTP<base> { public: virtual bool vf() {} }; class _single_inheritance derived: public base {};
Ezt nem fogadja el, hogy multiple_inheritance kell neki. Ha kitörlöm hogy ": CRTP<base>" akkor viszont elfogadja, akkor is ha beteszem a base *p; mezőt, ami ugyanaz mintha ": CRTP<base>" lenne. Mivel ugyanaz, el kellene fogadnia ősként is. Nem értem mi a különbség, miért nem fogadja el. Mivel nekem egy tolakodó AVL-elem CRTP-ősosztályom van, nem tudom mellőzni a CRTP-t, túl nagy munka lenne az összes template-es AVL-rutint csak emiatt megírni rá. Mi ez, valami bug a Visual C++ 16.11.5 fordítóban? Köszönöm.
Mutasd a teljes hozzászólást!
Nem értek ezekhez a dolgokhoz, de nekem is bugnak tűnik. Most indítottam én is egy VS-t és tudtam reprodukálni. A furcsa az, hogy ha a c0-ba rakok virtuális metódust (lehet virtuális destruktor is), akkor lefordul szépen. Akkor is lefordul, ha a c1-ben nincs virtuális metódus. Valahogy abba kavarodhat bele, hogy a c0-nak nincs vtable-je, a c1-nek meg már van.
Mutasd a teljes hozzászólást!

  • Milyen baj történne, ha teljesen kihagynád ezt a _single_inheritance kulcsszót?
    Mutasd a teljes hozzászólást!
  • A doksi szerint bizonyos pointerek nagyobbak lennének a minimálisan szükségesnél. Azt, hogy ez mennyire baj az adott esetben, x00 tudná pontosan megmondani, de gondolom van oka rá hogy spóroljon a memóriával.
    Mutasd a teljes hozzászólást!
  • Csak egy tipp, de változik valami, ha a base-t forward-deklarálod?

    class _single_inheritance base; template<class t> class CRTP { t *p; }; class _single_inheritance base: CRTP<base> { public: virtual bool vf() {} }; class _single_inheritance derived: public base {};
    Mutasd a teljes hozzászólást!
  • error C2292: 'c2': best case inheritance representation: 'single_inheritance' declared but 'multiple_inheritance' required

    a hibaüzenet a legleszármazottabbnál, és már ebben az egészen egyszerű példában is jelentkezik:

    class c0 {}; class c1: c0 { virtual void f() {} }; class _single_inheritance c2: c1 {};

    Próbáltam úgy is hogy az egész elejére kiírtam hogy class _single_inheritance c1; de nem segített (Csaboka2 kérdezte). 2-3 mutatónyi méretet foglalnának el a mutatók rájuk. Igazából nem gond, jelenleg is megjegyzésbe tettem hogy _single_inheritance és úgy lefordul. Nekem bugnak tűnik a fordítóprogramban.
    Mutasd a teljes hozzászólást!
  • Nem értek ezekhez a dolgokhoz, de nekem is bugnak tűnik. Most indítottam én is egy VS-t és tudtam reprodukálni. A furcsa az, hogy ha a c0-ba rakok virtuális metódust (lehet virtuális destruktor is), akkor lefordul szépen. Akkor is lefordul, ha a c1-ben nincs virtuális metódus. Valahogy abba kavarodhat bele, hogy a c0-nak nincs vtable-je, a c1-nek meg már van.
    Mutasd a teljes hozzászólást!
  • "Valahogy abba kavarodhat bele, hogy a c0-nak nincs vtable-je, a c1-nek meg már van."

    Igen, viszont ennek nem kellene problémát okoznia, hiszen ha c0 mezőit bemásoljuk c1-be, akkor az pont ugyanaz, és az meg lefordul. Bejelentettem:

    Multiple inheritance is required at the most derived class, without multiple inherition - Visual Studio Feedback
    Mutasd a teljes hozzászólást!
  • Én is ezt néztem, és úgy értettem, hogy akkor van jelentősége, amikor a deklarált osztály definíciója nem látszik, ezért ezzel a hint-tel informáljuk a compilert.

    Itt viszont definícióról van szó, a derék compiler saját maga látja, hogy miből és hogyan örököl az illető osztály; tehát ha ez a hint megegyezik azzal, amit a compiler gondol, akkor felesleges, ha nem egyezik meg, akkor zavart okoz.
    Mutasd a teljes hozzászólást!
  • Ez mondjuk jogos. Lehet, hogy a kód más részén ugyanez megvan forward deklarációval is, csak a biztonság kedvéért a definícióban is megismétli? (Csak tippelgetek.)

    A másik, hogy csak a pointer-to-member változók méretére vonatkozik. Amennyire én értem, a pointer-to-member eleve egy elég speciális dolog, de lehet hogy x00 pont használja ezt a funkcionalitást.
    Mutasd a teljes hozzászólást!
  • Nincs meg forward deklarációval. Ennél nem használom a mezőmutatót, másnál igen, csak furcsa volt hogy miért van így. Kitöröltem mert ott tényleg felesleges, de be van jelentve az MS-nek a hiba.

    A mezőmutató azt adja meg, hogy az adott mező címe mennyivel nagyobb, mint az objektum címe, aminek a mezője. Az értéke tehát egy mező lehet, a mező eléréséhez kell az objektum címe is. Vagyis ha mondjuk 2 int mezője van, ezzel megadható hogy melyik legyen az.
    Mutasd a teljes hozzászólást!
  • Nincs meg forward deklarációval.

    Akkor már én se értem. Ahogy NevemTeve írta, semmit nem használ, ha ott írod ki, ahol a fordító már egyébként is látja az ősosztályok listáját.

    A mezőmutató azt adja meg, hogy az adott mező címe mennyivel nagyobb, mint az objektum címe, aminek a mezője. Az értéke tehát egy mező lehet, a mező eléréséhez kell az objektum címe is. Vagyis ha mondjuk 2 int mezője van, ezzel megadható hogy melyik legyen az.

    Ezzel tisztában vagyok, csak a use case-t nem látom, ahol erre szükség van. Nem mondom, hogy soha semmire nem jó, csak nekem eléggé szélső esetnek tűnt, ami nem gyakran fordul elő egy programban (és ezért nem erre összpontosít az ember, ha optimalizálni akar).
    Mutasd a teljes hozzászólást!
  • Amikor itt a kérdést feltettem, még nem tudtam hogy az ott felesleges. Ettől még hibás a fordító, így az MS-nek bejelentve marad.

    Máshol függvényeknek adom meg, hogy melyik mezőt használja, például az egyik paramétere ez, a másik meg hogy azzal a mezővel mit csináljon: mondjuk ha halmaz, akkor mit tegyen bele. Például konstruktornál még előre nem tudjuk a címét, de van hivatkozásszámlálós típus is, aminél a kívül használt típus csak egy mutatót tartalmaz: na annál így nem kell kiolvasni a privát mutató tartalmát. Vagyis akkor használjuk, amikor az objektum címe ismeretlen, aminek a mezője.
    Mutasd a teljes hozzászólást!
  • Köszönöm a segítséget egyébként mindkettőtöknek.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd