Ich schreibe eine reine Header-Bibliothek, die die Klasse X im Header x.hpp definiert. Die Implementierung von X ist für verschiedene Standardversionen unterschiedlich:
Code: Select all
#if __cplusplus < 201703
class X {
int a;
};
#else
class X {
char b;
short c;
};
#endif
Wenn x.hpp in verschiedenen Client-Übersetzungseinheiten a.cpp und b.cpp enthalten ist, die mit ${CXX} -std=c++11 -c a.cpp und ${CXX} -std=c++20 -c b.cpp kompiliert und miteinander verknüpft werden, erzeugt dies stillschweigend eine fehlerhafte Binärdatei, da ODR-Verstöße IF-NDR sind.
In der Praxis kann ich Inline-Namespaces wie folgt verwenden:
Code: Select all
#if __cplusplus < 201703
inline namespace before_cpp17 {
class X {
int a;
};
}
#else
inline namespace cpp17_or_later {
class X {
char b;
short c;
};
}
#endif
Aber das hilft nur, wenn X vom Client-Code in einer Weise verwendet wird, die sich auf die Namensverzerrung einer Nicht-Inline-Funktion auswirkt (z. B. als Parameter), sodass der Linker die Funktionsdefinition nicht finden kann. Es hilft nicht, wenn X als Basis oder Datenelement einer Klasse verwendet wird.
Welche Optionen habe ich? Kann ich etwas in x.hpp einfügen, das Linkerfehler verursacht, dann ist die Standardversion inkonsistent, unabhängig davon, wie der Clientcode X verwendet?