Ich habe einen Fall, in dem Lookup und Überladungsauflösung anders verhält:Überlastung Auflösung, Namenssuche und Funktionszeiger
- für benutzerdefinierte Klasse vs eingebauten Typen vs std :: string
- für den direkten Aufruf vs Funktionszeiger Anruf
ich nicht, was genau Teile der Norm diese verschie rechtfertigen herausfinden kann Zensuren.
Betrachten Sie den folgenden C++ 11-Code:
#include <iostream>
#include <string>
using namespace std;
struct Test1 {};
struct Test2 {};
template<typename T>
int f(T t) { return 0; }
int f(Test1 t) { return 10; }
int f(int y) { return 20; }
template<typename T>
int use1() { return f(T()); }
template<typename T>
int use2() { auto fp = static_cast<int(*)(T)>(&f); return (*fp)(T()); }
int f(Test2 t) { return 30; }
int f(string s) { return 40; }
int f(double y) { return 50; }
int main() {
cout << "use1<float>: " << use1<float>() << endl;
cout << "use1<Test1>: " << use1<Test1>() << endl;
cout << "use1<int>: " << use1<int>() << endl;
cout << "use1<Test2>: " << use1<Test2>() << endl;
cout << "use1<string>: " << use1<string>() << endl;
cout << "use1<double>: " << use1<double>() << endl;
cout << endl;
cout << "use2<float>: " << use2<float>() << endl;
cout << "use2<Test1>: " << use2<Test1>() << endl;
cout << "use2<int>: " << use2<int>() << endl;
cout << "use2<Test2>: " << use2<Test2>() << endl;
cout << "use2<string>: " << use2<string>() << endl;
cout << "use2<double>: " << use2<double>() << endl;
return 0;
}
Ausgang ist (gleich mit g ++ 6.3 und Klirren ++ 5.0.0 Stamm):
use1<float>: 0
use1<Test1>: 10
use1<int>: 20
use1<Test2>: 30
use1<string>: 0
use1<double>: 0
use2<float>: 0
use2<Test1>: 10
use2<int>: 20
use2<Test2>: 0
use2<string>: 0
use2<double>: 0
Fragen :
- Warum unterscheidet sich
use1<string>
vonuse1<Test2>
? Beide Typen werden "an der Spitze" deklariert, beide f() Überladungen werden am Ende deklariert. - Warum unterscheidet sich
use1<Test2>
vonuse1<double>
? Entsprechende f() - Überlastungen liegen auf benachbarten Linien, gibt es etwas Spezielles in der Behandlung von eingebauten Typen? - Warum unterscheidet sich
use1<Test2>
vonuse2<Test2>
? Der Typ eines in use2 funktionierenden Zeigers scheint mit dem aufrufenden Kontext in use1 übereinzustimmen.
Danke! In Bezug auf use2: Gibt es einen Weg in use2 einen Funktionszeiger zu erhalten, der die Adresse der exakt gleichen Überladung von f() enthält, die in use1 aufgelöst wird? –
salmin
Ich kann mir keinen Weg vorstellen, einen Namen zu "verpfänden". Der Standard sieht nur die zweite Nachschlagephase vor, wenn der Name in einem direkten Funktionsaufruf verwendet wird, 'name (some_args)', und nicht in anderen Fällen, in denen eine Überladungsauflösung durchgeführt werden muss. –