2016-07-15 10 views
7

Ich habe eine offizielle Antwort auf this question, die decltype sollte nicht Triggerfunktion Kompilierung. Tatsächlich ist decltype für eine Funktion, die deklariert, aber nicht definiert ist, legal.Sollte die Adresse einer Templatisierten Funktion die Kompilation auslösen?

Nächste Frage, sollte unter der Adresse einer Funktion die Erstellung einer Funktion auslösen? Nehmen this example:

template <typename T> 
void foo(T&& x) { x.func(); } 

int main() 
{ 
    auto bar = &foo<int>; 
} 

All Compiler ich getestet habe nicht mit einem Fehler wie:

Antrag auf Mitglied func in x, die int von Nicht-Klasse-Typ ist

Aber wenn ich nur foo definiere und es nicht deklariere, kompiliert der Code gut. Kann mir jemand eine offizielle Quelle geben, ob die Adresse einer Funktion die Kompilierung erfordert?

+1

Nach http://en.cppreference.com/w/cpp/language/definition%23One_Definition_Rule „ein Objekt ODR-Adresse verwendet, wenn seine genommen wird“, und „Wenn ein Objekt oder eine Funktion ist odr- verwendet, muss seine Definition irgendwo im Programm existieren, eine Verletzung davon ist ein Link-Zeit-Fehler ". Ich habe nicht die relevanten Standard-Anführungszeichen, um dies zu einer Antwort zu machen – KABoissonneault

+0

@KABoissonneault Ich bin damit einverstanden. Wenn Sie http://en.cppreference.com für beide Zitate zitieren könnte, würde ich das offiziell genug betrachten. –

+0

@KABoissonneault Es sieht aus wie [was Sie zitiert] (http://en.cppreference.com/mwiki/index.php?title=cpp/language/definition&diff=prev&oldid=73909) geschrieben wurde von [Cubbi] (http ://Paketüberfluss.com/users/273767/cubbi) Ich wünschte, es gäbe einen Weg, um ihn zu begrüßen und mehr Informationen darüber zu bekommen. –

Antwort

2

3,2/2:

Ein Ausdruck ist potentiell ausgewertet, wenn es sich um eine nicht ausgewertete Operand (Ziffer 5) oder ein Unterausdruck davon ist. ... Eine nicht überladene -Funktion, deren Name als potenziell evaluierter Ausdruck oder als Mitglied einer Menge von Kandidatenfunktionen erscheint, wenn durch Überladung Auflösung ausgewählt, wenn von einem potenziell bewerteten Ausdruck ausgegangen wird, ist odr-used , es sei denn, es handelt sich um eine reine virtuelle Funktion und ihr Name ist nicht explizit .

Dann 3.2/3:

Jedes Programm wird genau eine Definition eines jeden nicht-inline Funktion oder Variable enthalten, die in diesem Programm-ODR verwendet wird; keine Diagnose erforderlich. Die Definition explizit im Programm erscheinen kann, kann es in der Standard- oder eine benutzerdefinierte Bibliothek zu finden, oder (wenn angemessen) implizit definiert ist (siehe 12.1, 12.4 und 12.8 ). Eine Inline-Funktion soll in jeder Übersetzungseinheit definiert sein, in der sie verwendet wird.

Der Funktionsname ist auf keinen Fall ein unevaluierten Operanden (zB sizeof, decltype), und es scheint, in einem Ausdruck, so dass es möglicherweise ausgewertet. Dann benötigt der zweite genau eine Nicht-Inline-Definition oder identische Inline-Definitionen in jeder Übersetzungseinheit.

+0

Dies ist der Kern Ihrer Logik: "Eine nicht überladene Funktion, deren Name als potentiell erscheint- ausgewerteter Ausdruck ... ist odr-used "Aber ich sehe nicht, wo die Adresse der Funktion es auswertet. Zum Beispiel 'declltype (foo (int {13}))' evaluiert nicht 'foo'. Ist '& foo ' es auszuwerten? Ich bin nicht sicher von diesen Zitaten. –

+2

@ Jonathan Mee Der Standard * explizit besagt, dass Kontexte wie ein Operand zu "Decltype" nicht potenziell ausgewertet werden, aber dass in einem anderen Kontext, wenn ein Name in einem Ausdruck angezeigt wird, potenziell ausgewertet wird. –

+0

@JonathanMee Denken Sie daran, wie könnte 'bar' möglicherweise als Funktionszeiger funktionieren, ohne 'foo ' instanziiert zu haben? Dies ist der gleiche Umstand, bei dem Sie Linker-Fehler mit Dingen wie 'static const int = 4; int j; std :: min (i, j) ' – Barry

Verwandte Themen