Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Faire un set de Vector2  (Lu 1997 fois)

0 Membres et 2 Invités sur ce sujet

Demystificator

  • Newbie
  • *
  • Messages: 40
    • Voir le profil
Faire un set de Vector2
« le: Septembre 10, 2015, 09:26:21 pm »
Bonjour,

J'essaie dans un de mes codes de créer un std::set de Vector2i.

Mais seulement voilà ; le compilateur me crache dessus en disant que insert() n'appelle pas l'opérateur correctement :

no match for 'operator<' (operand types are 'const sf::Vector2<int>' and 'const sf::Vector2<int>')|

L'erreur se trouve dans stl_function.h et l'opérateur est appelé par ce code :

    std::set<sf::Vector2i>* res;

    for(int i = 0; i < taille_cote; i++){
        for(int j = 0; j < taille_cote; j++) {
            if(test_vertical(i,j)){
                for(int k = -2; k < 1; k++){
                    res->insert(sf::Vector2i(i,j+k)); //L'erreur est appelee d'ici
                }
            }

De ce que je comprends, insert appelle l'opérateur < qui n'est pas défini pour Vector2i. Y a t'il une solution pour contourner ça ?

Le but étant d'obtenir dans res, des Vector2i uniques, sans aucun doublon.
Est ce que passer par pair fonctionnerait ? Dois-je écrire moi même l'opérateur < pour Vector2i ?

J'utilise MinGW 4.8.1 (GCC) et la SFML 2.3.1 (compilée sans problème), donc impossible d'utiliser unordered_set.

Merci d'avance pour vos réponses.
« Modifié: Septembre 10, 2015, 09:36:50 pm par Demystificator »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Faire un set de Vector2
« Réponse #1 le: Septembre 11, 2015, 07:41:35 am »
Pourquoi un std::set ? Ce code ne va, de toute évidence, jamais générer le moindre doublon puisque tu itères séquentiellement sur les i, les j et les k. Un simple std::vector suffirait.

Sinon, il faut que tu crées un prédicat perso qui se chargera de comparer deux sf::Vector2i, et que tu le passes en second paramètre template de ton std::set.

struct CompareVector2i
{
    bool operator()(sf::Vector2i a, sf::Vector2i b) const
    {
        if (a.x < b.x)
            return a;
        else if (b.x < a.x)
            return b;
        else
            return a.y < b.y;
    }
};

std::set<sf::Vector2i, CompareVector2i> set;
Laurent Gomila - SFML developer

Demystificator

  • Newbie
  • *
  • Messages: 40
    • Voir le profil
Re : Faire un set de Vector2
« Réponse #2 le: Septembre 11, 2015, 02:14:09 pm »
Le doublon peut être créé mais ça ne se voit pas dans ce petit bout de code.

J'essaie de coder un match3 comme Candy Crush, et res devra contenir tous les jetons alignés. Seulement il peut arriver qu'un jeton soit aligné à la fois verticalement et horizontalement et je dois récupérer 5 jetons alignés et non 6 pour pas fausser mes calculs sur le score.

Juste en dessous avec le code, je fais la même chose avec test_horizontal.

Donc, merci pour le prédicat.

Par contre, il me pose d'autres soucis  :

Citer
This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options.

A cet endroit là dans Config.hpp, ligne 186 :

    #if defined(_MSC_VER)
        typedef signed   __int64 Int64;
        typedef unsigned __int64 Uint64;
    #else
        typedef signed   long long Int64; //ici
        typedef unsigned long long Uint64; //et la
    #endif

Il m'indique aussi que logiquement, le prédicat ne peut ni renvoyer a ou b qui sont des Vector2i, alors que l'opérateur doit renvoyer un booléen. Si je traffique un peu le prédicat pour renvoyer un booléen; il ne me reste plus que le problème de l'iso 2011.

Mais quand j'active -stc=c++11 ; j'ai une erreur dans math.h, ligne 635 carrément :

Citer
c:\mingw\include\math.h|635|error: '_hypot' was not declared in this scope|

/* 7.12.7.3  */
extern double __cdecl hypot (double, double); /* in libmoldname.a */
extern float __cdecl hypotf (float, float);
#ifndef __NO_INLINE__
__CRT_INLINE float __cdecl hypotf (float x, float y)
{ return (float)(_hypot (x, y)); } //ici
#endif
extern long double __cdecl hypotl (long double, long double);
« Modifié: Septembre 11, 2015, 02:16:36 pm par Demystificator »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Faire un set de Vector2
« Réponse #3 le: Septembre 11, 2015, 02:32:00 pm »
Citer
Il m'indique aussi que logiquement, le prédicat ne peut ni renvoyer a ou b qui sont des Vector2i, alors que l'opérateur doit renvoyer un booléen.
Oups, pardon, j'ai été un peu vite.

struct CompareVector2i
{
    bool operator()(sf::Vector2i a, sf::Vector2i b) const
    {
        if (a.x < b.x)
            return true;
        else if (b.x < a.x)
            return false;
        else
            return a.y < b.y;
    }
};
 

En ce qui concerne le problème sur les types 64 bits, c'est vraiment bizarre.
Laurent Gomila - SFML developer

Demystificator

  • Newbie
  • *
  • Messages: 40
    • Voir le profil
Re : Faire un set de Vector2
« Réponse #4 le: Septembre 11, 2015, 03:26:15 pm »
Oui du coup on se retrouve avec le même prédicat.
Il y a également un warning du compilateur dans Config.hpp est :

Citer
C:\Cpp\SFML\SFML-2.3.1-sources\SFML-2.3.1\include\SFML\Config.hpp|186|warning: ISO C++ 1998 does not support 'long long' [-Wlong-long]|

Donc il semble plutôt bloquer sur la déclaration du type ; que long long ne semble pas être compatible avec les anciens iso.

Mais si c'est une question de quantité de bits j'avoue avoir un peu pris le compilateur sans trop me poser la question et il me semble travailler avec un compilateur 32bits et mon OS est en 64bits. Est ce que cela pourrait expliquer pourquoi il rejette les 64 ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Faire un set de Vector2
« Réponse #5 le: Septembre 11, 2015, 03:38:28 pm »
Citer
Est ce que cela pourrait expliquer pourquoi il rejette les 64 ?
Non. Comme le dit ton compilateur, le type "long long" n'existe pas dans l'ancien standard C++. Mais jusqu'à présent je n'ai jamais vu une seule version de gcc ne pas supporter correctement ce type, c'est pour ça que je trouve cette erreur vraiment bizarre. Cela a sans doute à voir avec ta variante/version de gcc, et/ou tes options de compilation.
Laurent Gomila - SFML developer

Demystificator

  • Newbie
  • *
  • Messages: 40
    • Voir le profil
Re : Faire un set de Vector2
« Réponse #6 le: Septembre 11, 2015, 05:30:06 pm »
J'ai eu des problèmes avec ce compilateur sur bullet ; une classe ne compilait pas et on m'a dit que ça venait que minGW ou gcc 4.8 avait raté quelque chose.

Voilà donc le topo, j'ai téléchargé MinGW contenant le GCC; j'ai pris mon CodeBlocks sans son compilateur, donc je suis sûr que tout passe par l'installation MinGW.

GNU Make 3.82.90

gcc -v :
Citer
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=m
ingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto
--enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++
,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-l
ibstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gm
p-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --
with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-
libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/
mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)

Mon Code::Blocks (je note uniquement ce qui est coché) :
-Wall (active tous les warnings)
-s (Réduit la taille en retirant des symboles de l'exe)
-O2 (optimisation pour gagner du temps)

Pas de define, pas d'autres options de projet.

S'il y a besoin de plus d'infos sur l'installation MinGW ; c'est la dernière version donnée par leur programme MinGW Installation Manager.

Ca viendrait plutôt du MinGW ou du GCC ? Car si je dois changer, autant savoir quoi changer déjà.