/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Problemer med at indsætte objekter i et se~
Fra : enrique


Dato : 19-02-03 02:16

Jeg er ved at "oversætte" et program jeg har skrevet i Java, til C++ for at
lære C++. Jeg er løbet ind i et problem når jeg skal indsætte et objekt i
et set. Og jeg fatter simpelt hen ikke fejlen:

g++ -Wall -c -o Budget.o Budget.cpp
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_function.h: In
member function `bool std::less<_Tp>:erator()(const _Tp&, const _Tp&)
const [with _Tp = Entry]':
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_tree.h:1042: instantiated from `std::pair<std::_Rb_tree_iterator<_Val, _Val&, _Val*>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(const _Val&) [with _Key = Entry, _Val = Entry, _KeyOfValue = std::_Identity<Entry>, _Compare = std::less<Entry>, _Alloc = std::allocator<Entry>]'
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_set.h:155: instantiated from `std::pair<std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, _Alloc>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = Entry, _Compare = std::less<Entry>, _Alloc = std::allocator<Entry>]'
Budget.cpp:87: instantiated from here
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_function.h:197: no
match for `const Entry& < const Entry&' operator
make: *** [Budget.o] Fejl 1

Fejlen sker her:

set<Entry> Budget::hentPosteringer()
{   
   set<Entry> posteringer;
   
   Entry ny("John", 1000, 1, 1, 5);
   
   posteringer.insert(ny); // Linie 87
   return posteringer;
}

Jeg har søgt rundt på google.com og i groups.google.com men ikke fundet
noget jeg kan forstå.

Jeg håber der er en der vil hjælpe mig, evt henvise mig til en side hvor
problemet står forklaret.

--
Mvh. / Kind regards
Henrik Farre

http://www.cs.auc.dk/~enrique


 
 
Mogens Hansen (19-02-2003)
Kommentar
Fra : Mogens Hansen


Dato : 19-02-03 07:13


"enrique" <look@mysignature.txt> wrote

> Jeg er ved at "oversætte" et program jeg har skrevet i Java, til C++ for
at
> lære C++. Jeg er løbet ind i et problem når jeg skal indsætte et objekt i
> et set. Og jeg fatter simpelt hen ikke fejlen:

Det er almindeligt og forståeligt at man lige mister overblikket, de første
gange man får sådan en fejlmelding smidt i hovedet.

>
> g++ -Wall -c -o Budget.o Budget.cpp
>
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_function.h:
In
> member function `bool std::less<_Tp>:erator()(const _Tp&, const
_Tp&)
> const [with _Tp = Entry]':
>
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_tree.h:1042
: instantiated from `std::pair<std::_Rb_tree_iterator<_Val, _Val&, _Val*>,
bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::insert_unique(const _Val&) [with _Key = Entry, _Val = Entry,
_KeyOfValue = std::_Identity<Entry>, _Compare = std::less<Entry>, _Alloc =
std::allocator<Entry>]'
>
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_set.h:155:
instantiated from `std::pair<std::_Rb_tree<_Key, _Key, std::_Identity<_Key>,
_Compare, _Alloc>::const_iterator, bool> std::set<_Key, _Compare,
_Alloc>::insert(const _Key&) [with _Key = Entry, _Compare =
std::less<Entry>, _Alloc = std::allocator<Entry>]'

<OBS !!! Den vigtige del af fejlmeldingen>

> Budget.cpp:87: instantiated from here
>
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/g++-v3/bits/stl_function.h:
197: no
> match for `const Entry& < const Entry&' operator

</OBS !!! Den vigtige del af fejlmeldingen>

> make: *** [Budget.o] Fejl 1

Ja, det er jo en hurtig lille fejlmelding, hvor man nemt kan se hvad der er
galt :-/
Man vænner sig til den slags fejlmeldinger, så fat mod.
Alternativt kan det være en idee at kigge på STLFilt
(http://www.bdsoft.com/tools/stlfilt.html) - den er efter sigende ikke så
tosset endda.

[8<8<8<]
> Jeg håber der er en der vil hjælpe mig, evt henvise mig til en side hvor
> problemet står forklaret.

Nøglen til at forstå problemet, er at forstå klassen "std::set".
Set er en container, der understøtter unike nøgler. Det betyder at den skal
have en måde at sammenligne nøglen for forskellige objekter på.

Den fuldstændige erklæring af template klassen "std::set" er
template <class Key, class Compare = less<Key>,
class Allocator = allocator<Key> >
class set;
hvor du kan se at første template argument er er typen på objekter som skal
opbevares.
Andet template argument er algoritmen der skal bruges til at sammenligne
nøglen for 2 objekter. Default er "std::less" som simpelthen bruger "<".
Her har du så dit problem:
Du har ikke specifieret hvordan "std::set" skal sammenligne 2 "Entry"
objekter, så derfor bruger den default og prøver at finde
bool operator<(const Entry&, const Entry&);
som formodentlig ikke findes.

Løsningen er defor en af følgende
* Gør det muligt for "std::set" at sammenligne 2 objekter
* Brug en anden container type (f.eks. "std::vector") og tænk lige over
hvorfor du valgte "std::set" til at begynde med (det er en glimrende
container)

En anden ting du skal være opmærksom på, er at alle containerne i C++
Standard Library gemmer objekterne by-value. De tager alså en kopi af
objektet og gemmer det - det er således ikke en pointer eller reference der
gemmes. Altså en opførsel som array i core-language.

Venlig hilsen

Mogens Hansen

PS
Det svære ved at oversætte et program fra et sprog til et andet er ikke så
meget syntaksen, som det er at forstå hvordan "det nye" sprog bruges på en
god måde.
Jeg kan varmt anbefale at kigge på bogen
Accelerated C++
Andrew Koenig, Barbara E. Moo
ISBN 0-201-70353-X
som er vældigt god (men dog ikke ville have hjulpet dig med dit konkrete
spørgsmål)



enrique (19-02-2003)
Kommentar
Fra : enrique


Dato : 19-02-03 13:17

On Wed, 19 Feb 2003 07:13:17 +0100, Mogens Hansen wrote:

> Det er almindeligt og forståeligt at man lige mister overblikket, de
> første gange man får sådan en fejlmelding smidt i hovedet.

Ja det, javac er lidt venligere :)

> Man vænner sig til den slags fejlmeldinger, så fat mod. Alternativt kan
> det være en idee at kigge på STLFilt
> (http://www.bdsoft.com/tools/stlfilt.html) - den er efter sigende ikke så
> tosset endda.

Det vil jeg gøre.

> Løsningen er defor en af følgende
> * Gør det muligt for "std::set" at sammenligne 2 objekter * Brug en
> anden container type (f.eks. "std::vector") og tænk lige over
> hvorfor du valgte "std::set" til at begynde med (det er en glimrende
> container)

Jeg valgte std::set pga dovenskab :), jeg ville være sikker på kun at
returnere unike Entry objekter, så i stedet for give mig til at tjekke om
objektet allerede findes, så tænkte jeg at det ville være meget lettere
bare at bruge en container der kun kan indeholde unike objekter :)

> Det svære ved at oversætte et program fra et sprog til et andet er ikke
> så meget syntaksen, som det er at forstå hvordan "det nye" sprog bruges
> på en god måde.

Ja, jeg har en del jeg skal have læst :)

> Accelerated C++
> Andrew Koenig, Barbara E. Moo
> ISBN 0-201-70353-X
> som er vældigt god (men dog ikke ville have hjulpet dig med dit konkrete
> spørgsmål)

Det vil jeg kraftigt overveje, når jeg engang får plus på kontoen igen ;)

Mange tak for det gode svar, det er sgu' dejligt at få sådan et svar når
man er kørt total fast, bliv endeligt ved med det!

--
Mvh. / Kind regards
Henrik Farre

http://www.cs.auc.dk/~enrique


Igor V. Rafienko (19-02-2003)
Kommentar
Fra : Igor V. Rafienko


Dato : 19-02-03 13:45

[ look@mysignature.txt ]

[ ... ]

> Jeg valgte std::set pga dovenskab :), jeg ville være sikker på kun
> at returnere unike Entry objekter, så i stedet for give mig til at
> tjekke om objektet allerede findes, så tænkte jeg at det ville være
> meget lettere bare at bruge en container der kun kan indeholde unike
> objekter :)


Det er nok riktig. Men hadde det vært Java med dens HashSet eller
OrderedSet, så måtte du ha implementert enten din egen equals(), eller
hele Comparator interfacet. Tilsvarende krav finnes i C++ (og
begrunnelsen for dette kravet er relativt opplagt -- man kan ikke
snakke om unike objekter før man har definert hva "unik" betyr for den
aktuelle typen).

Dersom din Entry-type har en underliggende identitet med "mindre enn"
operatoren definert for den aktuelle identiteten, kan du bruke dette
for å definere "mindre enn" relasjonen for Entry:


struct Entry {
T identity;
/* ... */
};

bool
operator<( const Entry &e1, const Entry &e2 )
{
return e1.identity < e2.identity;
}

(En forutsetning er at kravene stilt til "mindre enn" av std::set
overholdes også av T sin operator "mindre enn").





ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
            -- pederst på irc

enrique (19-02-2003)
Kommentar
Fra : enrique


Dato : 19-02-03 14:26

On Wed, 19 Feb 2003 13:44:54 +0100, Igor V. Rafienko wrote:

> Det er nok riktig. Men hadde det vært Java med dens HashSet eller
> OrderedSet, så måtte du ha implementert enten din egen equals(), eller
> hele Comparator interfacet. Tilsvarende krav finnes i C++ (og begrunnelsen
> for dette kravet er relativt opplagt -- man kan ikke snakke om unike
> objekter før man har definert hva "unik" betyr for den aktuelle typen).

Ja mit Java program bruger

if (!posteringer.contains(tmpEntry))
{
      posteringer.add(tmpEntry);
}

Hvor posteringer er en Linkedlist

> struct Entry {
> T identity;
> /* ... */
> };
>
> bool
> operator<( const Entry &e1, const Entry &e2 ) {
> return e1.identity < e2.identity;
> }

Kanon! Det begynder jo at give mening på så mange planer nu :)

--
Mvh. / Kind regards
Henrik Farre

http://www.cs.auc.dk/~enrique


Søg
Reklame
Statistik
Spørgsmål : 177491
Tips : 31966
Nyheder : 719565
Indlæg : 6408458
Brugere : 218886

Månedens bedste
Årets bedste
Sidste års bedste