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

Visual C++ Discussion :

[Debutant C++] Pb fonction surchargée sous .Net et pas VC6


Sujet :

Visual C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 1
    Points
    1
    Par défaut [Debutant C++] Pb fonction surchargée sous .Net et pas VC6
    Bonjour
    tout d'abord, veuillez m'excuser si je n'emploie pas les bons termes pour le C++, les habitudes sont tenaces..!

    J'ai un code (c++) qui se compile tres bien sous VC6 et qui me sort une erreur sous VC7 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error C2668: 'MAPSOLEType::String::Find'*: appel ambigu à une fonction surchargée
    Je ne comprends pas cette difference de comportement plateforme.

    Je vous joint une partie du code, j'espere que je n'ai rien oublié pour l'analyse
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class String // just an extract !
    {
        friend class Buffer;
    public:
    // Searching (return starting index, or 0 if not found)
        // like "C" strstr
        int Find(String& s, FindFlags ff = ffNone, Long iStart = -1) const;
        int Find(LPCWSTR wsz, FindFlags ff = ffNone, Long iStart = -1) const;
        int Find(LPCSTR sz, FindFlags ff = ffNone, Long iStart = -1) const;
        // Like "C" strchr
        int Find(WCHAR wch, FindFlags ff = ffNone, Long iStart = -1) const;
        int Find(CHAR ch, FindFlags ff = ffNone, Long iStart = -1) const;
    };
    
    
    inline int String::Find(String& s, FindFlags ff, Long iStart) const
    {
        return (Find(s.m_bs, ff, iStart));
    }
    
    inline int String::Find(LPCSTR sz, FindFlags ff, Long iStart) const
    {
        return (Find(String(sz), ff, iStart)); // <----- ERROR !!!!!!!!!!!!!
    }
    
    inline int String::Find(CHAR ch, FindFlags ff, Long iStart) const
    {
        return (Find(CharToWChar(ch), ff, iStart));
    }
    Avez vous une solution, et surtout une explication, je ne comprends vraiment pas cette erreur (VC6 est plus permissif que VC7et> ? )

    merci
    stephane

  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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Il faudrait voir avec quelle surcharge il n'arrive pas à se décider (normalement il le dit juste après le message d'erreur).

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    c'est vrai, j'ai oublié cette partie !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     error C2668: 'MAPSOLEType::String::Find'*: appel ambigu à une fonction surchargée
    : peut être 'int MAPSOLEType::String::Find(LPCSTR,MAPSOLEType::FindFlags,MAPSOLEType::Long) const'
       ou       'int MAPSOLEType::String::Find(LPCWSTR,MAPSOLEType::FindFlags,MAPSOLEType::Long) const'
    lors de la tentative de mise en correspondance de la liste des arguments '(MAPSOLEType::String, MAPSOLEType::FindFlags, MAPSOLEType::Long)'
    est ce suffisant ?

  4. #4
    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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Sans voir le reste de la classe, l'explication la plus probable est que ta classe String possède un opérateur de conversion implicite en LPCSTR et en LPCWSTR. La surcharge prenant un String& n'est pas candidate car tu ne peux pas passer un temporaire non nommé en tant que référence non constante.

    Prend déjà un const String& au lieu d'un String&, et ça réglera peut-être l'ambiguité.

    PS : si ton membre m_bs est un LPCSTR tu risques de tourner en rond.

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    il y a deja un cast ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        // Cast LPSTR to LPCSTR
        const String& operator=(LPCSTR sz);
    j'avoue ne pas savoir ou faire celui que tu preconises!
    je pose toute la partie concernée (j'ai enlevé des choses qui me semble inutiles a ce pb!) :
    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
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    // Some macros for casting and text conversion
    typedef WCHAR       _WCHAR;
    typedef CHAR        _CHAR;
    #define _WTEXT(t)   LPCWSTR(L ## t)
    #define _W(t)       LPCWSTR(L ## t)
    #define _WC(c)      WCHAR(L ## c)
    #define _NTEXT(t)   LPCSTR(t)
    #define _N(t)       LPCSTR(t)
    #define _BTEXT(t)   String(_W(t))
    #define _B(t)       String(_W(t))
    #define WNULL       LPCWSTR(NULL)
    #define BNULL       String(WNULL)
     
    // Helper converts LPSTR to BSTR
    BSTR SysAllocStringA(LPCSTR sz);
    BSTR SysAllocStringLenA(LPCSTR sz, unsigned cch);
     
    typedef Long FindFlags;
    const FindFlags ffNone = 0x0;
    const FindFlags ffReverse = 0x1;
    const FindFlags ffIgnoreCase = 0x2;
     
    //@B String1
    class String
    {
        friend class Buffer;
    public:
    // Constructors
        String();
        String(const String& s);
        // Danger! C++ can't tell the difference between BSTR and LPWSTR. If
        // you pass LPWSTR to this constructor, you'll get very bad results,
        // so don't. Instead cast to constant before assigning.
        String(BSTR bs);
        // Any non-const LPSTR or LPWSTR should be cast to LPCSTR or LPCWSTR
        // so that it comes through here
        String(LPCSTR sz);
        String(LPCWSTR wsz);
        // Filled with given character (default -1 means unitialized allocate)
        String(int cch, WCHAR wch = WCHAR(-1));
     
    // Destructor
        ~String();
    //@E String1
     
    // Assignment
        const String& operator=(const String& s);
        // BSTR only -- use const version for character strings
        const String& operator=(BSTR bs);
        // Cast LPSTR to LPCSTR
        const String& operator=(LPCSTR sz);
        // Cast LPWSTR to LPCWSTR
        const String& operator=(LPCWSTR wsz);
        const String& operator=(CHAR ch);
        const String& operator=(WCHAR wch);
     
    // Type casts
        operator BSTR() const;                  // as a const OLE BSTR
        operator BSTR();                        // as an OLE BSTR
        operator LPCSTR();                      // as a const ANSI string
        operator LPCWSTR();                     // as a const Unicode string
        // No LPSTR operator (use Buffer object)
     
    // Attributes & Operations
        int Length() const;
        int LengthZ() const;                // Length to first null
        BOOL IsEmpty();
        BOOL IsNull();
        void Empty();                       // Make an empty string
        void Nullify();                     // Make a null string
        String& NullIfEmpty();             // Return null for empty (handy for APIs)
     
        // Indexing
        WCHAR& operator[](int i);
     
        // String concatenation
        const String & operator+=(const String& string);
        const String & operator+=(WCHAR wch);
        const String & operator+=(CHAR ch);
        const String & operator+=(LPCWSTR wsz);
        const String & operator+=(LPCSTR sz);
     
        friend String operator+(const String& string1, const String& string2);
        friend String operator+(const String& string, const WCHAR wch);
        friend String operator+(const WCHAR wch, const String& string);
        friend String operator+(const String& string, const CHAR ch);
        friend String operator+(const CHAR ch, const String& string);
        friend String operator+(const String& string, BSTR bs);
        friend String operator+(BSTR bs, const String& string);
        friend String operator+(const String& string, LPCWSTR wsz);
        friend String operator+(const String& string, LPCSTR sz);
        friend String operator+(LPCWSTR wsz, const String& string);
        friend String operator+(LPCSTR sz, const String& string);
     
    // Searching (return starting index, or 0 if not found)
        // like "C" strstr
        int Find( String& s, FindFlags ff = ffNone, Long iStart = -1) const;
        int Find(LPCWSTR wsz, FindFlags ff = ffNone, Long iStart = -1) const;
        int Find(LPCSTR sz, FindFlags ff = ffNone, Long iStart = -1) const;
        // Like "C" strchr
        int Find(WCHAR wch, FindFlags ff = ffNone, Long iStart = -1) const;
        int Find(CHAR ch, FindFlags ff = ffNone, Long iStart = -1) const;
     
        friend ostream& operator<<(ostream& os, String& s);
     
    //@B String2
    private:
        BSTR   m_bs;            // The Unicode data
        LPSTR  m_pch;           // ANSI representation of it
        Boolean m_fDestroy;     // Destruction flag
     
        // Implementation helpers
        void Concat(int c, LPCWSTR wsz);
        void Destroy();
        void DestroyA();
     
    public:
    	// Bruno STEUX 2000 : added a usefuel little function
    	void MustBeDestroyed() {m_fDestroy=True;}
    };
    //@E String2
     
     
    // Buffer object for non-const string parameters
    class Buffer
    {
    public:
    // Constructor
        Buffer(String& s);
        Buffer(String& s, Long c);
     
    // Destructor
        ~Buffer();
     
    // Conversion operator
        operator LPSTR();
        operator LPWSTR();
     
    private:
        String * m_ps;
     
    // No assignment allowed (declared private, but not defined)
        Buffer& operator=(const Buffer&);
        Buffer(const Buffer&);
    };
     
    // iostream helpers
     
    // manipulator for CrLf sequence
    inline ostream& __cdecl endcl(ostream& os) { return os << "\r\n" << flush; }
    ostream& operator<<(ostream& os, WCHAR wch);
     
     
    // Implementation of inline functions
     
    //@B StringCon
    inline String::String()
        : m_bs(SysAllocString(NULL)), m_pch(NULL), m_fDestroy(True)
    {
    }
     
    inline String::String(const String& s)
        : m_bs(SysAllocString(s.m_bs)), m_pch(NULL), m_fDestroy(True)
    {
    }
     
    // Convert BSTR to String
    inline String::String(BSTR bs)
        : m_bs(bs), m_pch(NULL), m_fDestroy(False)
    {
    }
     
    inline String::String(LPCWSTR wsz)
        : m_bs(SysAllocString(wsz)), m_pch(NULL), m_fDestroy(True)
    {
    }
    inline String::String(LPCSTR sz)
        : m_bs(SysAllocStringA(sz)), m_pch(NULL), m_fDestroy(True)
    {
    }
    //@E StringCon
     
    //@B StringDes
    inline String::~String()
    {
        Destroy();
    }
     
    // Invalidate ANSI buffer
    inline void String::DestroyA()
    {
        if (m_pch) {
            delete[] m_pch;
            m_pch = NULL;
        }
    }
     
    //@E StringDes
     
    inline String::operator BSTR() const
    {
        return (BSTR)m_bs;
    }
     
    inline String::operator BSTR()
    {
        return SysAllocString(m_bs);
    }
     
    inline String::operator LPCWSTR()
    {
        return m_bs;
    }
     
     
    inline const String& String::operator+=(const String& s)
    {
        Concat(s.Length(), s.m_bs);
        return *this;
    }
     
    inline const String& String::operator+=(WCHAR wch)
    {
        Concat(1, &wch);
        return *this;
    }
     
    inline const String& String::operator+=(LPCWSTR wsz)
    {
        Concat(wcslen(wsz), wsz);
        return *this;
    }
     
     
    inline int String::Find(String& s, FindFlags ff, Long iStart) const
    {
        return (Find(s.m_bs, ff, iStart));
    }
     
    inline int String::Find(LPCSTR sz, FindFlags ff, Long iStart) const
    {
        return (Find(String(sz), ff, iStart));
    }
     
    inline int String::Find(CHAR ch, FindFlags ff, Long iStart) const
    {
        return (Find(CharToWChar(ch), ff, iStart));
    }

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Ici:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        operator LPCSTR();                      // as a const ANSI string
        operator LPCWSTR();                     // as a const Unicode string
    Le compilo ne sait lequel choisir puisque les deux conviennent à ta fonction.
    Tu dois soit passer par un pointeur en variable intermédiaire, soit forcer le choix du cast avec un static_cast<>.

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    arrgghhhh, je m'enfonce !

    vu que je ne saisi pas trop le coup du pointeur, je me dirige sur le cast.
    Vu que le compilo accepte les 2, le cast vas donc le forcer a utiliser la meme fonction avec le param convertit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        operator LPCSTR();                      // as a const ANSI string
        operator static_cast<LPCSTR>LPCWSTR();                     // as a const Unicode string
    ca doit donner un truc dans ce genre ?

    [sorry for noise]

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Trooooooooooooooop pas!
    Mais je me suis trompé aussi, je croyais que la "bonne" fonction de recherche était l'une des deux (LPCWSTR/LPCSTR).

    Le problème n'est pas ça : Le problème, c'est que tu passes un temporaire non-nommé à ta fonction Find(); résultat, le compilo refuse d'utiliser la fonction qui prend un String & en paramètre.

    Normalement, si tu remplaces String & par String const &, ça devrait marcher, car les temporaires non-nommés sont acceptés pour les références constantes.

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    hum..
    j'ai fait la fonction et sa definition comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        int Find( String const & s, FindFlags ff = ffNone, Long iStart = -1) const;
     
    inline int String::Find(String const & s, FindFlags ff, Long iStart) const
    {
        return (Find(s.m_bs, ff, iStart));
    }
    ca gueule encore plus fort : C1001 erreur interne compilo!!

    y'a pas moyen de forcer le compilo a ignorer cette nouveauté (vu que ca marche sous VC6), ou c'est en dur ?
    merci

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    C'est forcément en dur à mon avis, car je pense que c'est suite à un bug de VC6 que ça marchait.

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Je n'ai aucune idee de ce que pouvait bien faire VC++ 6.0 plutot que de donner un message d'erreur.

    Personnellement, je pense qu'il y a une erreur de conception fondamentale a donner autant de conversions implicites et de surcharges. Les deux vont mal ensemble.

    Le code a faire marcher, c'est celui avec: Find(String const & s, essaie de voir ce qui cause l'erreur interne. Au pire, reduit tout au minimum et poste ton code complet.

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    C'est simple, VC++ 6.0 acceptait les temporaires non-nommés pour une fonction demandant une référence non-constante.

    D'ailleurs, je crois bien que c'est un bug connu. En tout cas, c'était marqué dans la liste des breaking changes quelque part entre VC6 et VC++ 2005...

Discussions similaires

  1. Equivalent de la fonction ShellExecute sous VB.NET?
    Par Miss Ti dans le forum VB.NET
    Réponses: 4
    Dernier message: 20/06/2016, 16h19
  2. [POO] Fonction ok sous firefox mais pas sous ie
    Par 1r2R1 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 16/04/2009, 11h55
  3. fonction fonctionnant sous IE et pas sous FF
    Par dubitoph dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 02/07/2007, 13h09
  4. Réponses: 2
    Dernier message: 26/03/2007, 17h25
  5. Fonction EXTRACT sous Informix
    Par lord_of_ankou dans le forum Informix
    Réponses: 3
    Dernier message: 20/08/2003, 17h37

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