2

Je suis en train de compiler une erreur dans VS2010 avec du code qui compile proprement dans VS2008.Erreur de compilation dans VC++ 2010 (clean in 2008!), "Appel ambigu à une fonction surchargée"

Voici mon erreur, de la fenêtre de sortie, avec toutes ses verbosité:

...\elementimpl.h(49): error C2668: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string' : ambiguous call to overloaded function 
     with 
     [ 
      _Elem=char, 
      _Traits=std::char_traits<char>, 
      _Ax=std::allocator<char> 
     ] 
     c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(700): could be 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax> &&)' 
     with 
     [ 
      _Elem=char, 
      _Traits=std::char_traits<char>, 
      _Ax=std::allocator<char> 
     ] 
     c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(590): or  'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const _Elem *)' 
     with 
     [ 
      _Elem=char, 
      _Traits=std::char_traits<char>, 
      _Ax=std::allocator<char> 
     ] 
     while trying to match the argument list '(CXStr)' 

et est ici le code d'erreur, elementimpl.h (49):

std::string getAttributeValue(const char* attr) { return getAttribute(CXStr(attr)); } 

getAttribute() renvoie un CXStr (un ADT), ce qui n'est évidemment pas accepté par le constructeur std :: string, il doit donc convertir le CXStr en quelque chose de convenable.

CXStr peut être converti en soit un std :: string ou un char *:

class CXStr 
{ 
public: 
    ... 
    CXStr(std::string); 
    CXStr(const char* ch); 

    const CXStr& operator=(const char*); 
    const CXStr& operator=(std::string&); 

    operator char*(); 
    operator std::string(); 
    ... 
} 

Quand je lance à travers le débogueur dans VS2008, je peux voir qu'il passe par « CXStr opérateur :: std :: string() "après getAttribute(), puis il passe par le constructeur de la copie std :: string pour créer l'objet à renvoyer par getAttributeValue(). Je veux que mon build 2010 se comporte de la même manière.

Mes questions:

  • Qu'est-ce que VS2010 fait différemment, et pourquoi?
  • Quelle modification de code puis-je apporter à corriger cette erreur? Certaines choses qui travail, mais ne sont pas satisfaisants:
    1. commentant "CXStr :: opérateur char *()"; insatisfaisant car certains autre code utilise cette conversion.
    2. appelez explicitement "getAttribute (...). Opérateur std :: string()" at elementimpl.h (49); désagréable parce que cette même erreur se produit dans 27 endroits différents et il semble comme il doit y avoir une manière plus centralisée pour le réparer.
+0

Quelle est la déclaration de 'getAttribute'? – GManNickG

+0

CXStr getAttribute (const XMLCh * pAttr); – feuGene

Répondre

3

Le problème est que VS2010 a ajouté des constructeurs de déplacement et que votre implémentation tombe directement dans ce trou.

Auparavant, il n'y avait qu'un seul constructeur, le const char * un, qui était disponible pour le constructeur std :: string. Maintenant, il y a le constructeur de mouvement, aussi. Je pense vraiment qu'une conception basée sur des conversions implicites est dangereuse. C'est pourquoi tous les constructeurs de paramètres doivent être explicites ...

Je pense que vous devriez déconseiller l'utilisation d'opérateurs implicites, car ils entraînent de mauvaises surcharges.Si vous ne pouvez pas faire cela, enveloppez les appels qui échouent actuellement dans un appel de conversion explicite std::string(CXStr(x).toString()). Il peut y avoir d'autres erreurs cachées en utilisant des opérateurs de cast non explicites.

0

Pourquoi ne vous a essayé commentant l'opérateur std :: string() encore?

Vous pouvez également transtyper votre CXStr en std :: string. Franchement cependant, je ne peux pas voir l'utilisation de cette chose CXStr. Qu'offre-t-il, le cas échéant, en matière de services?

+0

Comme je l'ai dit, comme construit dans VS2008, "CXStr :: operator std :: string()" est le chemin de conversion choisi, et je veux préserver ce comportement, donc éliminer cet opérateur semble une non-option pour moi. – feuGene

+0

J'ai essayé de remplacer elementimpl.h (49) par "std :: string getAttributeValue (const char * attr) {return static_cast (getAttribute (CXStr (attr)));}", mais le compilateur s'est plaint: "... \ elementimpl.h (49): erreur C2440: 'static_cast': impossible de convertir 'CXStr' en 'std :: string' [\ n] Aucun constructeur n'a pu prendre le type source, ou la résolution de surcharge du constructeur était ambiguë " – feuGene

+0

à CXStr que l'extrait que j'ai collé dans la question. Son utilisation principale est la conversion depuis et vers des chaînes compatibles Xerces-C++ (avec des éléments de type XMLCh *, qui est UTF-16). – feuGene

Questions connexes