gcc 8.0.0 und clang 5.0 .0 stimmt nicht mit dem Verhalten dieses Programms überein:
%Vor% Das Verhalten von gcc macht für mich keinen Sinn - wenn die const T&
Überladung der U&&
Überladung für lvalue const int
vorgezogen wird, warum ist nicht die T&&
Überladung gegenüber der U&&
Überladung für rvalue int
? Klänge machen mehr Sinn für mich (keine der Funktionen ist spezialisierter als die andere, so gewinnt der Deduktionsführer).
Wer hat Recht?
Wir sind wieder in teilweisem Land. Der Typ der synthetisierten Funktionsschablonenparameter ist
%Vor%Die Transformation vor der partiellen Sortierung entfernt die Referenznummer und danach die Top-Level-CV-Qualifikation , so dass wir in allen drei Fällen einen nackten Typ haben. Daraus folgt, dass in allen drei Fällen der Abzug in beide Richtungen gelingt. Wir sind jetzt mit [temp.deduct.partial] / 9 Tiebreaker zurück:
Wenn für einen gegebenen Typ der Abzug in beiden Richtungen erfolgreich ist (d. h Typen sind nach den obigen Transformationen identisch) und sowohl P als auch A waren Referenztypen (bevor sie durch den Typ ersetzt wurden, auf den verwiesen wird) oben):
- wenn der Typ aus der Argumentvorlage ein lvalue ist Referenz und der Typ aus der Parametervorlage war nicht, die Der Parametertyp gilt nicht als mindestens so spezialisiert wie der Argumenttyp; Andernfalls
- wenn der Typ aus der Argumentvorlage stammt ist cv-qualifiziert als der Typ aus der Parametervorlage (z. B. wie oben beschrieben), wird der Parametertyp nicht als mindestens betrachtet so spezialisiert wie der Argumenttyp.
Für U&&
vs T&&
gilt keine Regel und es gibt keine Bestellung. Für U&&
vs const T&
wird jedoch der Parametertyp U&&
nicht als mindestens so spezialisiert angesehen wie der Argumenttyp const T&
, je nach dem ersten Aufzählungszeichen.
Partielle Ordnung findet daher, dass # 2 spezialisierter als # 3 ist, aber findet, dass # 1 und # 3 nicht unterscheidbar sind. GCC ist korrekt.
Das heißt, dies kann ein Versehen in den Teilordnungsregeln sein. Klassenvorlagenabzug ist das erste Mal, dass wir einen "rvalue-Verweis auf cv-unqualifizierte Vorlagenparameter haben, der keine Weiterleitungsreferenz ist". Zuvor, in Double-Reference-Fällen, verlieren Forwarding-Referenzen immer an nicht weiterleitende Rvalue-Referenzen im zweiten Aufzählungszeichen (weil der einzige Weg, auf den Sie Nicht-Weiterleitungs-Rvalue-Referenzen bekommen, ist, wenn Sie cv T&&
für einige nichtleere cv
haben ).
Tags und Links c++ templates language-lawyer c++17 deduction-guide