eine Situation vorstellen, wo ich zwei verschiedene Übersetzungseinheiten a.cppWidersprüchliche Template-Definitionen und ODR
#include <iostream>
double bar();
template <typename T>
T foobar(T t) {
return t;
}
int main() {
std::cout << "foobar called from b.cpp: " << bar() << '\n';
std::cout << "foobar called from a.cpp: " << foobar(1.) << '\n';
}
und b.cpp haben:
template <typename T>
T foobar(T t) {
return t + 1.;
}
double bar() {
return foobar(1.);
}
Ich weiß, dass für Vorlagen, gibt es Ausnahmen von das ODR, dh der Compiler wird instanziierte Funktionsvorlagen als solche markieren und alle außer einem während des Verknüpfungsvorgangs streichen. Mir ist aufgefallen, dass es dem Compiler eigentlich egal ist, ob die generierten Codes solcher Instanziierungen bei verschiedenen Übersetzungseinheiten tatsächlich identisch oder zumindest äquivalent sind.
Im obigen Code ist dies der Fall. Beim Kompilieren, Verknüpfen und läuft mit
c++ a.cpp b.cpp -o result -std=c++17 && ./result
es das Ergebnis liefern wird
foobar called from b.cpp: 1
foobar called from a.cpp: 1
So offenbar, bekam weg für diese eine von u.a. zugunsten der Instanziierung innerhalb der Objektdatei b.o geworfen Beim Übersetzen und Binden mit b.cpp und a.cpp getauscht, wie
c++ b.cpp a.cpp -o result -std=c++17 && ./result
das Ergebnis wird
foobar called from b.cpp: 2
foobar called from a.cpp: 2
sein, so das genaue Gegenteil geschieht: die Instanziierung, die zuerst in der Liste erwähnt wurde von zu Verbundene Objektdateien sind diejenigen, die überlebt haben. Wird ein solches Verhalten irgendwo im Standard definiert? Je nach Build-System kann die Reihenfolge, in der die Objektdateien erwähnt werden, ziemlich willkürlich sein, aber wie in solchen Beispielen führt dies zu sehr unterschiedlichen Programmen und möglicherweise umständlichen Fehlern. Auch wenn ich die Version von a.cpp von bis explizit zu instanziiert versuchen Sie
template double foobar<double>(double);
es wird nicht das Foobar machen <> Vorlage aus a.cpp überleben, wenn sie vor a.o in der Linkerliste zu erwähnen b.o.
nur aus Neugier: Ist das eine rein akademische Frage, oder haben Sie einen echten Fall, in dem das ein Problem ist? Ich meine, du könntest die Vorlage nur einmal definieren und das Problem ist weg. – user463035818
Es sieht so aus, als ob du das Tag [tag: sprachanwalt] zu deiner Frage hinzufügen möchtest !? –
@WernerHenze, die meine Frage beantwortet;) – user463035818