C
audacia schrieb:
camper schrieb:
das ist aber nicht an so strikte Vorausetzungen (Die Definition muss ja in einem umliegenden Namensraum erfolgen) gebunden und insofern einfach genug.
Das versuche ich nun schon eine ganze Weile, bisher ohne Erfolg. Wie geht das denn so einfach?
Ein statischer Member wird implizit instantiiert, wen er in einer Weise benutzt wird, die die Existenz der Definition voraussetzt. Der einfachste Weg, der mir dazu einfällt, ist die Bestimmung der Adresse des Members.
Um die Adresse eines Objektes bestimmen zu können, muss dieses existieren, mithin definiert worden sein.
Das können wir ausnutzen, falls wir irgendeine Funktion haben, die sowieso implizit instantiiert wird. Eine nahe liegende Wahl ist der Destruktor - falls wir irgendwann einmal ein Objekt der Klasse benötigen, wird es sicherlich auch irgendwo zerstört werden, und dabei wird der Destruktor ggf. implizit instantiiert, einfach einen Ausdruck einfügen, der die Adresse bestimmt (dieser hat im Übrigen keine Seiteneffekte und erzeugt trivialerweise keinen Overhead - das bedeutet aber nicht, dass hier keine Nutzung vorliegt und der Compiler die Instantiierung einfach wegoptimieren darf):
#include <iostream>
template<typename T>
struct foo {
~foo() { &x; } // <<==, instantiiert implizit x
static foo<T> x;
};
template<typename T>
foo<T> make_foo() { std::cout << "make_foo\n"; return foo<T>(); }
template<typename T>
foo<T> foo<T>::x = make_foo<T>();
int main()
{
foo<int> a; // instantiiert implizit (neben anderen) foo<int>::~foo
}