5

J'ai ce petit extrait de code que j'aimerais obtenir un peu plus d'informations sur pourquoi la résolution de surcharge sélectionne un constructeur plutôt qu'un autre. Voici le code en question:Résolution de surcharge de constructeur C++ avec héritage multiple

#include <iostream> 

struct Base 
{ 

}; 

struct Other 
{ 
    Other(const Other&) 
    { 
     std::cout << "Copy Constructor\n"; 
    } 
    Other(const Base&) 
    { 
     std::cout << "Custom Constructor\n"; 
    } 
}; 

struct Derived : public Base, public Other 
{ 
    Derived() : 
     Other(*this) 
    { 

    } 
}; 

int main() 
{ 
    Derived derived; // Prints "Copy Constructor" 

    system("pause"); 
    return 0; 
} 

Je suppose qu'il ya une section dans la norme C++ qui définit le constructeur de copie comme une meilleure correspondance que l'utilisateur constructeurs définis *? Mon hypothèse était sinon que si aucune règle favorisant le constructeur de copie n'existait, alors le compilateur irait soit par l'ordre d'héritage (comme avec l'ordre de construction avec héritage multiple) soit me donnerait juste une erreur d'appel de constructeur ambigu. Cependant, inverser l'ordre dans lequel Derived hérite de Base et Other ne change pas la sortie, ce qui me porte à croire que ma supposition initiale sur les constructeurs de copie étant favorisée est correcte. Quelqu'un pourrait-il me diriger vers la règle qui détermine le comportement que je vois?

* J'ai vérifié cppreference.com's Overload Resolution page, mais je n'ai vu aucune règle qui pourrait expliquer le comportement que je vois (bien que je sois qui ne maîtrise pas parfaitement le standard, je l'aurais facilement manqué).

+3

Appel ambigu pour clang/gcc [Demo] (http://coliru.stacked-crooked.com/a/0319bddd762f37aa) – Jarod42

+0

Un appel ambigu dans mon compilateur ne sera pas compilé. – iheanyi

+1

Huh, intéressant. J'utilise Visual Studio 2017.3 (Preview), et il compile même avec le drapeau/permissive. Je suppose que c'est un comportement non standard de Visual Studio plutôt qu'un comportement non standard de Clang/GCC? –

Répondre

1

La raison pour laquelle l'extrait de code en question est dû à un comportement conforme standard de Visual Studio (j'utilise actuellement VS2017.3 Preview, qui compile le code sans erreur même avec le drapeau/permissive). Ci-dessous l'erreur émis par GCC et Clang:

GCC

Error(s): 
source_file.cpp: In constructor ‘Derived::Derived()’: 
source_file.cpp:25:20: error: call of overloaded ‘Other(Derived&)’ is ambiguous 
     Other(*this) 
        ^
source_file.cpp:16:5: note: candidate: Other::Other(const Base&) 
    Other(const Base&) 
    ^
source_file.cpp:12:5: note: candidate: Other::Other(const Other&) 
    Other(const Other&) 
    ^

Clang

Error(s): 
source_file.cpp:25:9: error: call to constructor of 'Other' is ambiguous 
     Other(*this) 
     ^ ~~~~~ 
source_file.cpp:12:5: note: candidate constructor 
    Other(const Other&) 
    ^
source_file.cpp:16:5: note: candidate constructor 
    Other(const Base&) 
    ^
1 error generated. 

Sortie d'erreur provenant http://rextester.com/.