1

この質問は、主にクラスのインスタンス化とテンプレートのインスタンス化という用語のために、言葉にするのが難しいです。静的関数とメンバーでいっぱいのテンプレート クラスがあります。このテンプレートを特殊化するたびに、最初に使用する前に初期化を行う必要があります。

私の最初の計画は、テンプレート クラスに静的メンバーを与えるだけ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 でテストしましたが、すべて同じ結果が得られました。私の静的メンバーは構築されていません。これにより、標準ではこの動作が必要であると思われますが、なぜそうなのか理解できません。

4

0 に答える 0