Sowohl gcc 4.9.0 20140302 als auch clang 3.5 (trunk 202594) wählen die erste Version korrekt aus. Als hvd gab mir freundlicherweise the references in comments:
Wenn für einen bestimmten Typen, gelingt es Abzug in beiden Richtungen (dh die Typen nach den Transformationen obigen identisch sind), und beide P
und A
waren Referenztypen (bevor sie mit der oben genannten Art ersetzt werden):
- Wenn der Typ aus der Argumentvorlage eine lvalue-Referenz und der Typ aus der Parametervorlage nicht war, wird der Argumenttyp als spezialisierter angesehen als der andere; andernfalls
- Wenn der Typ aus der Argumentvorlage mehr cv-qualifiziert ist als der Typ aus der Parametervorlage (wie oben beschrieben), wird der Argumenttyp als spezialisierter angesehen als der andere; ansonsten
- keiner der beiden Typen ist spezialisierter als der andere.
By the way, sehen The Universal Reference/Overloading Collision Conundrum Video, warum auf dem Universal-Referenzen Überlastung ist eine schlechte Idee. Kurz gesagt, betrachten Sie das folgende Beispiel:
#include <iostream>
#include <utility>
struct A { bool guts_stolen; };
void steal_guts(A&& a) {
a.guts_stolen = true;
}
template <typename T> void f(const T& a) {
// ^^^^^ note the const!
std::cout << "T&\n";
}
template <typename T> void f(T&& a) {
std::cout << "T&&\n";
steal_guts(std::move(a));
}
int main() {
A a{ false };
f(a);
std::cout << "Guts stolen? " << std::boolalpha << a.guts_stolen << std::endl;
}
Wenn Sie das Programm ausführen, wird es
T&&
Guts stolen? true
drucken, die überhaupt nicht das, was Sie durch einen Blick auf A a{ false }; f(a);
nur erwarten würde.
Sowohl die erste Version, mit 'T = A', als auch die zweite Version, mit' T = A & ', haben einen Parameter vom Typ' T & ', also auf welcher Basis kann man sagen, dass es richtig ist die erste Version wird ausgewählt? (Ich denke, du hast Recht, aber du solltest deine Antwort wirklich erklären.) – hvd
@hvd Ja, ich versuche den entsprechenden Abschnitt im Standard zu finden/ein gcc Bugreport in Bugzilla. – Ali
[Hier] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1164) und [hier] (http://gcc.gnu.org/bugzilla/show_bug. cgi? id = 57172) :) – hvd