この質問は、主にクラスのインスタンス化とテンプレートのインスタンス化という用語のために、言葉にするのが難しいです。静的関数とメンバーでいっぱいのテンプレート クラスがあります。このテンプレートを特殊化するたびに、最初に使用する前に初期化を行う必要があります。
私の最初の計画は、テンプレート クラスに静的メンバーを与えるだけinitializer
で、動的初期化での構築中にテンプレート クラスの静的メンバーを初期化することでした。
ただし、これは機能しません。クラスでコードを明示的に呼び出さない限りinitializer
、コンパイラはそのコードやストレージを生成しません。
例えば:
template<typename Tag>
class WorkerPool
{
struct WorkerInitializer
{
void foo() { }
WorkerInitializer() { WorkerPool<Tag>::start(); }
};
friend struct WorkerInitializer;
static WorkerInitializer _initializer;
static void start() { std::cout << "Started" << std::endl; }
public:
static void async() { std::cout << "Async" << std::endl; }
};
template<typename T> typename WorkerPool<T>::WorkerInitializer
WorkerPool<T>::_initializer;
struct GenericWorker { };
int main()
{
WorkerPool<GenericWorker>::async();
}
出力は単に「非同期」です。
WorkerPool<T>::async()
ただし、呼び出しを呼び出すように変更すると_initializer.foo()
、イニシャライザはコンパイルされ、正しく構築されます。期待どおりです。
コンパイラが静的メンバーのコード生成を拒否するのはなぜですか?
Visual Studio 2010/2012、gcc、clang でテストしましたが、すべて同じ結果が得られました。私の静的メンバーは構築されていません。これにより、標準ではこの動作が必要であると思われますが、なぜそうなのか理解できません。