[C++] set<Ctest> als member var in Ctest?

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Wat ik wil is dus het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <set>

class Ctest
{
    typedef std::set<Ctest> t_set;

    t_set m_set;
};

int main()
{
    return 0;
}

Maar van de compiler (en de taal waarschijnlijk) mag dit niet. Dat een class niet als member var binnen zichzelf gebruikt mag worden snap ik, maar in een set moet het toch kunnen?
Is dit een 'probleem' van de implementatie van std::set?
Als ik zelf een tree maak lijkt het me geen probleem.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Ik zeg ongetwijfeld iets stoms, maar wat als je er een pointer van maakt? Dan moet 't iig kunnen.


* drm weinig verstand van templates

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • whoami
  • Registratie: December 2000
  • Nu online
Een class mag idd geen members hebben van z'n type, maar wel een pointer naar z'n eigen type.
Ik geloof dat dat probleem ook in een ander topic besproken werd vorige week, maar ik heb het topic niet echt meer gevolgd....
[rml]whoami in "[ c++] design- en coding-styles"[/rml]

https://fgheysels.github.io/


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Maar m_set is een tree en geen Ctest. Ik heb nu een oplossing met pointers, maar niet zoals gesuggereerd werd.
Ik gebruik t_set& m_set.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 29-08 03:21

.oisyn

Moderator Devschuur®

Demotivational Speaker

het zou imho idd gewoon moeten werken... std::set alloceert intern gewoon een buffertje

tenzij het een statische buffer gebruikt zodat kleine sets niet die rompslomp van new hoeven te hebben... en dan zit je dus met een probleem :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

std::set sorteert zijn elementen met een object van het tweede template parameter type, dat default naar std::less<Key>. std::less vergelijkt met behulp van operator<. Voor jouw class is geen operator< (of specialisatie van std::less) aanwezig. Gevolg: Comeau geeft een error bij de declaratie van je set<..>, g++ geeft (pas) een error bij het instantieren van bijvoorbeeld de insert member.

Na het toevoegen van een operator< compileren zowel g++ als Comeau de code zonder problemen.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dat is geen probleem, de volgende code compileert namelijk wel:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma warning(disable: 4503)
#pragma warning(disable: 4786)
#pragma warning(disable: 4800)

#include <set>

class Ctest
{
public:
    typedef std::set<Ctest> t_set;

    Ctest():
        m_set(*new t_set)
    {
    }
private:
    t_set& m_set;
};

int main()
{
    Ctest test;
    return 0;
}

Verwijderd

OlafvdSpek schreef op 04 november 2002 @ 15:51:
Dat is geen probleem, de volgende code compileert namelijk wel:
Dat is wel een probleem, alleen heb je er hier nog geen last van omdat je geen members instantieert die vergelijkings operaties op de elementen uitvoeren.

Verwijderd

.oisyn schreef op 04 november 2002 @ 15:34:
het zou imho idd gewoon moeten werken... std::set alloceert intern gewoon een buffertje

tenzij het een statische buffer gebruikt zodat kleine sets niet die rompslomp van new hoeven te hebben... en dan zit je dus met een probleem :)
Ik denk niet dat de standaard set implementers verbied om member instances van het element type te gebruiken. Als dat inderdaad niet het geval is, kun je er dus niet (portable) vanuit gaan dat je set met een incomplete type kan instantieren (zoals hier gebeurt).

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

offtopic:
Heej, iemand anders gebruikt hetzelfde prefixsysteem als ik! Werkt best lekker toch Olaf? ;)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Mmmm voor zover ik kan zien klopt het dat die eerste code niet compileert. In de diepte van de set-implementatie (bij VC.net iig) sta je namelijk een recursieve class te genereren. Als je dit zou doen:
C++:
1
2
3
4
class Ctest
{
  Ctest        m_Test;
};

Krijg je error C2460 in VC.net. Tzou wel vriendelijker zijn als diezelfde code met templates dezelfde error zou geven...

Professionele website nodig?


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
curry684 schreef op 04 november 2002 @ 17:01:
offtopic:
Heej, iemand anders gebruikt hetzelfde prefixsysteem als ik! Werkt best lekker toch Olaf? ;)
Dat gebruik ik ook al een hele tijd sinds dat topic van jou (wel iets aangepast, maar ok) :) Bevalt me goed idd :)

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ja, werkt lekker.
curry684 schreef op 04 november 2002 @ 17:16:
Mmmm voor zover ik kan zien klopt het dat die eerste code niet compileert. In de diepte van de set-implementatie (bij VC.net iig) sta je namelijk een recursieve class te genereren. Als je dit zou doen:
C++:
1
2
3
4
class Ctest
{
  Ctest        m_Test;
};

Krijg je error C2460 in VC.net. Tzou wel vriendelijker zijn als diezelfde code met templates dezelfde error zou geven...
Komt dat misschien door de sentinel?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
std::set mag zo geschreven zijn dat het met incomplete classes werkt, maar dat hoeft niet. Ctest is duidelijk incomplete , de laatste } moet nog komen dus dat kan idd niet.

Een van de redenen hiervoor is dat de node geheugen allocator best een of andere _NodeAllocator<sizeof( CTest) > mag zijn (implementatie optimalisatie), en dat gaat nogal slecht als je sizeof() nog niet weet.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

OlafvdSpek schreef op 04 november 2002 @ 19:03:
Komt dat misschien door de sentinel?
Definieer sentinel? :? :z

Professionele website nodig?


Verwijderd

Voor de geinteresseerden: ik vond zojuist een interessant artikeltje over standard containers met incomplete types: The Standard Librarian: Containers of Incomplete Types.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 04 november 2002 @ 16:20:
Ik denk niet dat de standaard set implementers verbied om member instances van het element type te gebruiken. Als dat inderdaad niet het geval is, kun je er dus niet (portable) vanuit gaan dat je set met een incomplete type kan instantieren (zoals hier gebeurt).
Volgens de standaard mag je zo'n set niet eens instantieren.
The C++ Standard [8] says that you're not allowed to instantiate a standard library template with an incomplete type: "the effects are undefined ...

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
MSalters schreef op 05 november 2002 @ 01:10:
std::set mag zo geschreven zijn dat het met incomplete classes werkt, maar dat hoeft niet. Ctest is duidelijk incomplete , de laatste } moet nog komen dus dat kan idd niet.

Een van de redenen hiervoor is dat de node geheugen allocator best een of andere _NodeAllocator<sizeof( CTest) > mag zijn (implementatie optimalisatie), en dat gaat nogal slecht als je sizeof() nog niet weet.
Welke 'data' in set zelf (waar sizeof(set) dus van afhangt) is dan afhankelijk van de allocator?

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Het element waarnaar de iterator wijst die set::end() returned.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
OlafvdSpek schreef op 05 november 2002 @ 15:51:
[...]

Welke 'data' in set zelf (waar sizeof(set) dus van afhangt) is dan afhankelijk van de allocator?
De allocator zelf is in sommige implementaties een echte member van std::set.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

OlafvdSpek schreef op 05 november 2002 @ 15:44:
Volgens de standaard mag je zo'n set niet eens instantieren.

[...]
Daar was ik inmiddels ook achter, ik lees artikelen namelijk meestal ook eerst zelf voor ik ze post.. :)
Pagina: 1