IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Conflit avec "remove()"


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut Conflit avec "remove()"
    Bonjour à tous !

    Je travaille sous C++Builder 6 (10.161), et je rencontre un petit problème avec la fonction remove : en effet, il existe deux fonctions portant ce nom dans le namespace std.

    La première,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int remove(const char *)
    , dans cstdio (pour supprimer un fichier) ; la deuxième,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template <class ForwardIterator, class T>
    ForwardIterator remove(ForwardIterator first, ForwardIterator last,
                           const T& value);
    , dans algorithm (pour enlever des élèments d'un container, ou plutôt pour les déplacer en fin de container). Or, lorsque je souhaite utiliser la fonction template, j'obtiens une erreur du compilateur, indiquant qu'il ne sélectionne pas la bonne fonction. Est-ce normal d'avoir un tel conflit ?!

    Voici un code minimal qui ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <algorithm>
    #include <cstdio>
    #include <vector>
     
    int main()
    {
        std::vector<int> v;
     
        v.push_back(3);
        v.push_back(2);
        v.push_back(5);
     
        v.erase(std::remove(v.begin(), v.end(), 2), v.end());
     
        return 0;
    }
    Et l'erreur qu'il donne :
    [C++ Erreur] test_remove.cpp(13): E2034 Impossible de convertir 'int *' en 'const char *'
    [C++ Erreur] test_remove.cpp(13): E2342 Mauvaise correspondance de type dans le paramètre '__path' ('const char *' désiré, 'int *' obtenu)
    [C++ Erreur] test_remove.cpp(13): E2227 Paramètre supplémentaire dans l'appel à std::remove(const char *)
    [C++ Erreur] test_remove.cpp(13): E2285 Impossible de trouver une correspondance pour '_STL::vector<int,_STL::allocator<int> >::erase(int,int *)'
    Si quelqu'un a déjà rencontré cette erreur, ou sait à quoi elle est dûe...

    Edit : J'ai essayé de compiler ce même code sous code::blocks, et il n'y a aucun problème...dois-je en déduire que c'est le compilateur borland qui fait des siennes ?

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Edit : J'ai essayé de compiler ce même code sous code::blocks, et il n'y a aucun problème...dois-je en déduire que c'est le compilateur borland qui fait des siennes ?
    Possible, en tout cas ce bout de code semble tout à fait correct. Autre solution : inclure <stdio.h>, ainsi remove(const char*) ne sera pas dans le namespace std.

  3. #3
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Laurent Gomila
    Autre solution : inclure <stdio.h>, ainsi remove(const char*) ne sera pas dans le namespace std.
    Non, avec les formes xxx.h, les noms sont definis dans le namespace std et importes dans le namespace global.

  4. #4
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    J'ai essayé ta solution, mais ça n'a rien changé. Je suis aller voir dans stdio.h, et il utilise lui aussi le namespace std :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #ifdef __cplusplus
    namespace std {
    #endif /* __cplusplus */
    Tout cela est tout de même bizarre !

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Est-ce que remove est bien défini dans <algorithm>? Et comment? Fait attention aux macros et a la compilation conditionnelle.

  6. #6
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    Et bien, le fichier <algorithm> contient les inclusions conditionnelles suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef _USE_OLD_RW_STL
    # include <oldstl\algorith.h>
    #else
    # include <stlport\algorithm>
    #endif
    ainsi qu'un export dans le namespace global (si je ne m'abuse), mais qui n'est à priori pas effectué :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #if !defined(__USING_STD_NAMES__) && defined(__cplusplus)
    using namespace std;
    #endif /* __USING_STD_NAMES__ */
    Normalement, c'est le fichier <stlport\algorithm> qui est inclus, et il contient entre autres les lignes suivantes, avant d'inclure <stl/algo.h> :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # if ! defined (_STLP_USE_NAMESPACES)
    // remove() conflicts, <cstdio> should always go first
    #  include <cstdio>
    # endif
    Donc j'en déduis que normalement, le conflit ne devrait pas se présenter lorsque <cstdio> est inclus avant <algorithm>, mais ce n'est pas vraiment le cas...

    Quant à remove, il est bien défini dans <_algo.h>, de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class _ForwardIter, class _Tp>
    _STLP_INLINE_LOOP _ForwardIter 
    remove(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) {
      _STLP_DEBUG_CHECK(__check_range(__first, __last))
      __first = find(__first, __last, __value);
      if (__first == __last)
        return __first;
      else { 
        _ForwardIter __next = __first;
        return remove_copy(++__next, __last, __first, __value);
      }
    }

  7. #7
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    J'ai trouvé une explication sur un autre forum :

    Found a bug report. Apparently this arrises because parts of RogueWare's implementation is used. STLPort actually uses the _STL namespace which is aliased as stlport and _STLP_STD. So it resolves stlport::remove just fine, but std::remove resolves to the only remove actually in the std namespace. _STL is in std as well by a using, but apparently that causes the remove actually in std to be selected.
    Et effectivement, en utilisant stlport::remove, je n'ai plus de problèmes. Mais alors mon code n'est plus portable .

    Edit : Voici la solution donné par borland namespace resolution is failing. Ils conseillent d'utiliser remove_if ou de revenir à la l'implémentation de Rogue Wave plutôt que la stlport...

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo