Warum gibt es keine Mehrdeutigkeit?Warum die const lvalue-Referenz Vorrang hat gegenüber der const rvalue-Referenz während der Überlastungsauflösung
struct B {};
struct C {};
struct A
{
A(B const &, C const &) {}
A(B const &&, C const &&) = delete;
#if 0
A(B const &, C const &&) = delete;
A(B const &&, C const &) = delete;
#endif
};
B const b() { return {}; } // const result type may make sense
C const c() { return {}; } // for some user-defined types
int main()
{
A a0{B{}, C{}}; // I want to prohibit this
A a1{b(), c()}; // and this cases
B const bb{};
C const cc{};
A a2{b(), cc}; // But surely I also want to prohibit this
A a3{bb, c()}; // and this cases to compile
}
Hier möchte ich Lvalue const Verweise auf B
und C
Instanzen in die Instanz von A
zu speichern. Natürlich möchte ich sicherstellen, dass die Lebensdauer der referenzierten Objekte die Lebensdauer der Instanz A
überwindet.
Um dies ich nur = delete;
Überlastungen für B const &&
zu erreichen und C const &&
, die zusätzlich B &&
und C &&
entsprechend übereinstimmt.
Der obige Ansatz funktioniert perfekt für Conversion-Konstruktoren (d. H. Unäre). Aber es stellt sich heraus, dass für höhere Aritäten ich explizit alle kombinatorisch möglichen Kombinationen, die const rvalue Referenzversionen von Parametern von Interesse (d. H. #if 1
) umfasst = delete;
.
Dann denke ich: "Warum gibt es keine Zweideutigkeit?", - weil die Mehrdeutigkeit auch die Erstellung von falschem Code im obigen Fall verhindern sollte.
Also Frage ist: "Warum gibt es keine Mehrdeutigkeit für den Fall der Konstruktor Aufruf?".
'B const &&' bindet nicht an einen Lvalue. Dieser Konstruktor ist überhaupt nicht für "a3" geeignet; ebenfalls 'a2'. –
@ T.C. 'B const &' bindet an einen rvalue jeder Art. – Orient
Ja, aber nicht umgekehrt. Das ist der springende Punkt. –