2011-06-19 3 views
3

J'ai ces codes:C++ Constructor pour le type Implicite Conversion

class Type2 { 
public: 
    Type2(const Type1 & type); 
    Type2(int); 
const Type2 & operator=(const Type2 & type2); 
//.... 
}; 

... 
    Type1 t1(13); 
    Type2 t2(4); 

    t2=t1; 

Comme je l'ai compris, les constructeurs de type2 à 1 argument chacun sans explicite mot-clé devrait signifier des objets Type1 ou des valeurs int peut être implicitement conveted aux objets Type2.

Mais à la dernière ligne t2 = t1;, MS Visual Studio me donne cette erreur de compilation:

....error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Type1' (or there is no acceptable conversion)....

On dirait que MS Visual Studio insistant sur le fait t2 = t1; doit correspondre à un opérateur d'affectation avec lhs = Type2 et rhs = Type1. Pourquoi ne peut-il implicitement transtyper rhs en t2 et ensuite faire la copie avec l'opérateur Type2 = Type2?

+0

Ce code compile bien pour moi dans VS2010. –

+0

Je sais pourquoi. Parce que mon Type1 a un opérateur de conversion: class Type1 {operator Type2()}; – JavaMan

+0

Puis-je fermer une question pour laquelle j'ai trouvé la réponse moi-même? – JavaMan

Répondre

2

J'ai trouvé la réponse. Parce que mon Type1 a un opérateur de conversion

class Type1 { 
    public: 
     Type1 (int); 
     operator Type2() ;//casting to Type2 

    .... 
    }; 

C'est quelque chose appelé "conversion implicite à double sens"

+0

Intéressant. Cela compile bien dans GCC. –

+0

Oui, même VS2010 compile parfois. Mais je dois comprendre exactement quand. C'est la situation ambiguë standard que le compilateur ne peut pas dire quelle conversion doit être utilisée. À mon humble avis, ils devraient produire une erreur de compilation. – JavaMan

+0

@Oli Qu'est-ce qui compile? Je vois des extraits de code avec beaucoup de '...' s –

1

Ce code:

#include <iostream> 

using ::std::cerr; 

class Barney; 

class Fred { 
public: 
    Fred() { } 
    Fred(const Barney &b) { cerr << "Using conversion constructor.\n"; } 
}; 

class Barney { 
public: 
    Barney() { } 
    operator Fred() const { cerr << "Using conversion operator.\n"; return Fred(); } 
}; 

int main(int argc, const char *argv[]) 
{ 
    const Barney b; 
    Fred f; 
    f = b; 
    return 0; 
} 

génère cette erreur dans gcc 4.6:

g++ -O3 -Wall fred.cpp -o a.out 
fred.cpp: In function ‘int main(int, const char**)’: 
fred.cpp:23:8: error: conversion from ‘const Barney’ to ‘const Fred’ is ambiguous 
fred.cpp:21:17: note: candidates are: 
fred.cpp:16:4: note: Barney::operator Fred() const 
fred.cpp:10:4: note: Fred::Fred(const Barney&) 
fred.cpp:7:7: error: initializing argument 1 of ‘Fred& Fred::operator=(const Fred&)’ 

Compilation exited abnormally with code 1 at Sun Jun 19 04:13:53 

Maintenant, si j'enlève le const après operator Fred(), il compile ensuite et utilise le constructeur de conversion. Si je supprime également le const de la déclaration de b dans main, il préfère alors l'opérateur de conversion.

Tout cela correspond aux règles de résolution de surcharge. Et gcc génère l'erreur d'ambiguïté appropriée lorsqu'il ne peut pas choisir entre l'opérateur de conversion et le constructeur de conversion. Je remarque que dans les exemples que vous avez donnés, l'opérateur de conversion manque const. Cela signifie qu'il n'y aura jamais de cas dans lequel l'utilisation de l'opérateur de conversion ou du constructeur de conversion est ambiguë.

Questions connexes