C++ invalid comparator

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • switchboy
  • Registratie: September 2002
  • Laatst online: 30-06 22: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: 22:26

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:
  • 0 Henk '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
  • +2 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 22:26

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:
  • 0 Henk 'm!

  • switchboy
  • Registratie: September 2002
  • Laatst online: 30-06 22: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