Sind mehrere Instanzen derselben Klassenvorlage mit demselben Typ in verschiedenen Kompilierungseinheiten zulässig? Was ist mit Funktionsvorlagen?Verknüpfung expliziter Klassenvorlageninstanziierung
Ein Beispielcode ist wie folgt:
test.hpp
template <typename T>
class A
{
public:
T out();
};
template <typename T>
T A<T>::out()
{
return T(1);
}
test1.cpp
#include "test.hpp"
template class A<int>;
int testFn()
{
return A<int>().out();
}
test2.cpp
#include "test.hpp"
template class A<int>;
extern int testFn();
int main()
{
return testFn() == A<int>().out();
}
Wenn ich laufen
g++ -std=c++11 test1.cpp test2.cpp -o test
kompiliert, ohne sich zu beschweren, doppelte Definitionen.
Ich bezog mich auf alte Entwürfe von Standard [1] [2], und Annahme, dass die Verbindung Teil nicht zu viel ändert (außer für anonyme Namespaces). Die Klassenvorlage hat eine externe Verknüpfung von 3.5p4 und 14p4. Wenn das der Fall ist, würde ich erwarten, dass g ++ doppelte Definitionen von A :: out() beschweren sollte. Fehle ich hier etwas?
Was passiert, wenn test.hpp eine Funktionsvorlage ohne "static" oder "inline" definiert?
Vielen Dank.
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf [2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
[temp.spec] p5 * "Für eine gegebene Vorlage und einen gegebenen Satz von Template-Argumenten, - sollte eine explizite Instanziierungsdefinition höchstens einmal in einem Programm erscheinen [...] Eine Implementierung ist nicht erforderlich, um eine zu diagnostizieren Verletzung dieser Regel. "* – dyp
Siehe auch [CWG NAD 1045] (http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1045), die einen Grund enthält, warum dies wahrscheinlich nicht diagnostiziert. – dyp
@dyp, In diesem Fall verletzt mein Programm tatsächlich 14.7.0.5, aber der Standard besagt, g ++ ist nicht erforderlich, um dies zu diagnostizieren und tatsächlich g ++ löste die Multiple-Definition. Aber damit es normkonform ist, sollte ich alle Instanzen in nur einer Übersetzungseinheit definieren und explizite Template Instanziierung ("extern") in anderen Übersetzungseinheiten deklarieren. Hab ich recht? – nocte107