Warum können Vorlagen nicht in externen "C" -Blöcken sein?
Dies ist ein follow-up-Frage zu eine Antwort zu Ist es möglich, mit typedef einen Zeiger-auf-extern-"C"-Funktion geben Sie innerhalb von einer Vorlage?
Dieser code nicht kompilieren mit g++
Visual C/C++, und Comeau C/C++ im Grunde mit der gleichen Fehlermeldung:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
template <typename return_t_, typename arg1_t_>
struct test {
static void foo(return_t_ (*)(arg1_t_)) { }
};
}
int main()
{
test<int, int>::foo(&do_stuff);
return EXIT_SUCCESS;
}
g++ sagt "error: template mit C linkage", Visual C/C++ - compiler emittiert Fehler C2894und Comeau C/C++, sagt "Fehler: diese Erklärung kann nicht extern "C" Verknüpfung".
Die Sache ist, alle sind glücklich mit:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
struct test {
static void foo(int (*)(int)) { }
};
}
int main()
{
test::foo(&do_stuff);
return EXIT_SUCCESS;
}
Abschnitt 7.5, Linkage-Spezifikationen, von der C++ - Standard besagt:
Einem C-Sprache-Verknüpfung ignoriert, denn die Namen von class-member und die member-Funktion
die Art der Klasse member-Funktionen.
Und es gibt sogar das Beispiel:
extern "C" {
class X {
void mf(); //the name of the function mf and the member
//function's type have C++ language linkage
void mf2(void(*)()); //the name of the function mf2 has C++ language
//linkage; the parameter has type pointer to C function
};
}
Wenn Vorlagen erstellt wurden, dürfen in extern "C" - Blöcke, dann die member-Funktionen der Instanzen hätte C++ - Bindung.
Aber warum hat das Kapitel 14 Vorlagen, die C++98-Standard Zustand:
Einen Namen für die Vorlage haben kann linkage (3.5). Eine Vorlage, ein template explizite Spezialisierung (14.7.3), und eine Klasse Vorlage teilweise Spezialisierung nicht haben C linkage.
Was bedeutet es, dass eine Vorlage "können" haben-Gestänge? Was ist die Vorlage, die Bindung?
Warum ist es ausdrücklich untersagt, eine Vorlage haben, mit der C-Verknüpfung, wenn eine Klasse ist okay, und alle member-Funktionen von instantiierungen des template (der Standard-Konstruktor, Destruktor und Zuweisungsoperator überladen) hätte C++ linkage?
InformationsquelleAutor der Frage Daniel Trebbien | 2011-02-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alle Namen entweder haben externe Bindung, internal linkage haben oder keine linkage (C++03 §3.5p2), aber das ist nicht das gleiche Gestänge wie Sprache Gestänge. (Verwirrend, ich weiß. C++0x ändert die Dinge deutlich mit Gestänge, auch.) Externe Verbindung ist erforderlich für alles, was als template-argument:
Beachten Sie, dass C++98 hat "kann" in dem, was Sie zitiert §14p4, aber C++03 entfernt das "können", als Vorlagen deklariert werden können, in einem Kontext, der Ihnen interne Verlinkung:
InformationsquelleAutor der Antwort Fred Nurk
Vorlagen sind nicht eigentliche code, Sie sind nur Richtlinien, um den compiler für die Generierung des code, wenn die template-Parameter bekannt sind. Als solche sind Sie nicht wirklich existieren, bis Sie versuchen, Sie zu nutzen. Sie kann keine Bindung zu etwas, das nicht existiert.
InformationsquelleAutor der Antwort Mark Ransom
Weil template-Funktion Namen müssen geschmückt werden, mit zusätzlichen Informationen und
extern "C"
dreht Dekoration aus. Der Zweck derextern "C"
ist in der Lage sein zu erklären, - Funktionen, die aufgerufen werden kann mit C linkage, das ist etwas, das wird nie funktionieren mit einer template-Funktion offensichtlich.InformationsquelleAutor der Antwort Frederik Slijkerman
Weil
extern C
deaktiviert die name manglings die Vorlagen verwendenSehen, dass templates umgesetzt, die mit Namen, mangeln, kompilieren und dekompilieren:
mit:
Die Ausgabe enthält:
Beachten Sie, wie alle
callq
waren zu nennen seltsame Namen wie_Z1fIiET_S0_
.Das gleiche gilt für andere Eigenschaften, die davon abhängen, name mangling, z.B. das überladen von Funktionen.
Siehe auch: In C++ - Quelle, was ist die Wirkung von extern "C"?
InformationsquelleAutor der Antwort Ciro Santilli 新疆改造中心 六四事件 法轮功
Da es keine Vorlagen in C.
InformationsquelleAutor der Antwort Crazy Eddie