Toon posts:

C++ invalid comparator

Pagina: 1
Acties:

Vraag


Acties:
  • 0Henk 'm!

  • switchboy
  • Registratie: September 2002
  • Laatst online: 17-11 17:11

switchboy

-ruimte te huur-

Topicstarter
Mijn vraag
Ik wil van ontwikkelomgeving veranderen van code::blocks naar visual studio 2019 omdat code::blocks nou niet echt heel fijn schaalt op een 4K scherm en visual studio echt veel handige features heeft (zoals waarden van variables zien door een mouse hover als de code bij een breakpoint komt. Anyway ik heb SFML en het meest van mijn bestaande code geport en het compiled. Echter loop ik tegen een aantal dingen aan welke vallen onder undefined behavoir. Het meeste heb ik gefixed door kleine aanpassingen waardoor ik geen gebruik meer maak van dat soort dingen echter loop ik tegen één probleem aan waar ik mijn hoofd over blijf breken.

Ik heb een vector met hierin alle geselecteerde hokjes. Hier kunnen door de manier waarop ik die hokjes bepaal duplicaten inzitten. Nu gebruik ik std::sort en hierna std::unique en dan erase vanaf de pointer die unique teruggeeft tot het einde om hiervanaf te komen.

De vector bevat een struct met de x en de y coördinaat. Niks fancy dus.

De versimpelde code die dezelfde errors geeft ziet er als volg uit:

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <vector>
#include <algorithm> 

struct rectangleCord
{
    int x, y;
};


bool compareCord(rectangleCord& lhs, rectangleCord& rhs)
{
    return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
}

bool sortCordByX(rectangleCord& lhs, rectangleCord& rhs)
{
    return (lhs.x < rhs.x) || (lhs.y < rhs.y);
}

int main()
{
    std::vector<rectangleCord> rectangleCords;
    rectangleCords.push_back({ 1,2 });
    rectangleCords.push_back({ 2,2 });
    rectangleCords.push_back({ 2,1 });
    rectangleCords.push_back({ 2,2 });
    rectangleCords.push_back({ 3,2 });
    rectangleCords.push_back({ 4,1 });
    rectangleCords.push_back({ 5,2 });
    rectangleCords.push_back({ 4,2 });
    rectangleCords.push_back({ 5,2 });
    rectangleCords.push_back({ 1,1 });
    rectangleCords.push_back({ 1,2 });

    std::sort(rectangleCords.begin(), rectangleCords.end(), sortCordByX);
    rectangleCords.erase(std::unique(rectangleCords.begin(), rectangleCords.end(), compareCord), rectangleCords.end());

    std::cout << "Using sort, unique and erase:" << std::endl;
    for (unsigned int i = 0; i < rectangleCords.size(); i++)
    {
        std::cout << rectangleCords[i].x << " - " << rectangleCords[i].y << std::endl;
    }


    return 0;
}


Dit compiled en doet precies wat het moet doen in release mode. Echter in debug mode krijg ik de melding dat ik een "invalid comparator" heb. Dus ik denk dat iet hierin niet goed gaat:

code:
1
2
3
4
bool compareCord(rectangleCord& lhs, rectangleCord& rhs)
{
    return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
}

Niet een heel ingewikkeld stukje code; dit geeft true terug als zowel x en y hetzelfde zijn. Kan vrij weinig mee mis zijn lijkt me? |:(

Nu heb ik de volgende workaround bedacht via een unorderd_set:
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <vector>
#include <algorithm> 
#include <unordered_set>

struct rectangleCord
{
    int x, y;
};

namespace std {
    template <> struct hash<std::pair<int, int>> {
        inline size_t operator()(const std::pair<int, int>& v) const {
            std::hash<int> int_hasher;
            return int_hasher(v.first) ^ int_hasher(v.second);
        }
    };

}

int main()
{
    std::unordered_set<std::pair<int, int>> setOfCords;
    std::vector<rectangleCord> rectangleCords;
    rectangleCords.push_back({ 1,2 });
    rectangleCords.push_back({ 2,2 });
    rectangleCords.push_back({ 2,1 });
    rectangleCords.push_back({ 2,2 });
    rectangleCords.push_back({ 3,2 });
    rectangleCords.push_back({ 4,1 });
    rectangleCords.push_back({ 5,2 });
    rectangleCords.push_back({ 4,2 });
    rectangleCords.push_back({ 5,2 });
    rectangleCords.push_back({ 1,1 });
    rectangleCords.push_back({ 1,2 });
    for (unsigned int i = 0; i < rectangleCords.size(); i++)
    {
        setOfCords.insert({ rectangleCords[i].x, rectangleCords[i].y });
    }

    std::cout << "Using unorderd_list: " << std::endl;
    for (const std::pair<int, int>& i : setOfCords)
    {
        std::cout << i.first << " - " << i.second << std::endl;
    }
    return 0;
}

Het werkt maar geeft een extra kopieer stap en ik moet in de rest van het programma van een pair uitgaan ipv mijn struct met handig labletjes voor x en y. Geen ramp maar wel irritant.

Hebben jullie misschien een idee waarom debug mode over zijn nek gaat van mijn comperator?

My Steam Profile (Name Switch) Worth: 889€ (225€ with sales)Games owned: 83

Beste antwoord (via switchboy op 17-05-2020 22:49)


  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:02

RayNbow

Kirika <3

switchboy schreef op zondag 17 mei 2020 @ 16:51:
Hebben jullie misschien een idee waarom debug mode over zijn nek gaat van mijn comperator?
std::sort verwacht dat je comparator een strict weak ordering oplevert en dat doet jouw comparator niet.

Test dit maar eens:
C++:
1
2
3
4
5
6
7
8
9
10
int main()
{
    rectangleCord a{ 1,2 };
    rectangleCord b{ 2,1 };

    std::cout << "a < b = " << sortCordByX(a, b) << '\n';
    std::cout << "b < a = " << sortCordByX(b, a) << '\n';

    return 0;
}


Meer info kun je in dit antwoord op StackOverflow vinden.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir

Alle reacties


Acties:
  • 0Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Zou het niet
code:
1
bool compareCord(const rectangleCord& lhs, const rectangleCord& rhs)
moeten zijn?

Acties:
  • Beste antwoord
  • +2Henk 'm!
  • Pinned

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:02

RayNbow

Kirika <3

switchboy schreef op zondag 17 mei 2020 @ 16:51:
Hebben jullie misschien een idee waarom debug mode over zijn nek gaat van mijn comperator?
std::sort verwacht dat je comparator een strict weak ordering oplevert en dat doet jouw comparator niet.

Test dit maar eens:
C++:
1
2
3
4
5
6
7
8
9
10
int main()
{
    rectangleCord a{ 1,2 };
    rectangleCord b{ 2,1 };

    std::cout << "a < b = " << sortCordByX(a, b) << '\n';
    std::cout << "b < a = " << sortCordByX(b, a) << '\n';

    return 0;
}


Meer info kun je in dit antwoord op StackOverflow vinden.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0Henk 'm!

  • switchboy
  • Registratie: September 2002
  • Laatst online: 17-11 17:11

switchboy

-ruimte te huur-

Topicstarter
RayNbow schreef op zondag 17 mei 2020 @ 17:36:
[...]

std::sort verwacht dat je comparator een strict weak ordering oplevert en dat doet jouw comparator niet.

Test dit maar eens:
C++:
1
2
3
4
5
6
7
8
9
10
int main()
{
    rectangleCord a{ 1,2 };
    rectangleCord b{ 2,1 };

    std::cout << "a < b = " << sortCordByX(a, b) << '\n';
    std::cout << "b < a = " << sortCordByX(b, a) << '\n';

    return 0;
}


Meer info kun je in dit antwoord op StackOverflow vinden.
Ik zocht het bij de verkeerde functie

code:
1
2
3
4
5
6
7
8
9
bool sortCordByX(const rectangleCord& lhs, const rectangleCord& rhs)
{
    if (lhs.x != rhs.x) {
        return lhs.x < rhs.x;
    }
    else {
        return lhs.y < rhs.y;
    }
}


Heeft het opgelost

My Steam Profile (Name Switch) Worth: 889€ (225€ with sales)Games owned: 83




Google Pixel 7 Sony WH-1000XM5 Apple iPhone 14 Samsung Galaxy Watch5, 44mm Sonic Frontiers Samsung Galaxy Z Fold4 Insta360 X3 Nintendo Switch Lite

Tweakers is samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer onderdeel van DPG Media B.V.
Alle rechten voorbehouden © 1998 - 2022 Hosting door True

Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee