2016-08-24 5 views
1

Meyers Singletonは、local static variable initialization is atomicという事実に依存しています。C++は= atomicで静的変数を初期化していますか?

私は同様のものを構築していますが、シングルトンを実際にいくつかの派生型の1つにしたいと考えています。基底クラスgetInstance()メソッドは、適切な型を返すファクトリを呼び出す必要があります。

私の最初のアイデアは、N3337

static Foo *instance = FooFactory(...); 

8.5p2が、これは厳密に初期化していない初期化と代入であると私は文全体がアトミックであることを意味することを解釈することを示しているように思われます。これは正しいです?

ていない場合は声明

static Foo *instance(FooFactory(...)); 

は違うのでしょうか? C++ 11以降> 8.5.p2

答えて

1

8.5.2は "[dcl.init.string]"であり、関連性がないようです。私は8.5 para2を意味すると思います。

はい、厳密には初期化です(具体的にはコピー初期化 - 8.5 para14を参照)。

宣言が関数内にある場合は、the answer to the linked question showsとして、すべて正常です。

しかし、これが名前空間スコープの静的変数である場合、スレッドセーフであるために初期化を必要とするものは何も表示されません。 (それは初期化がスレッドを作成する場合にのみ問題ですが、それは可能です)。

+0

スレッドを作成する静的な初期化が見られる場合、私は直ちにそれを書いた開発者に関する経営陣の懸念を提起するでしょう:) – SergeyA

+0

DllMainの中のほとんど何でも実行しているWindows DLLについては、特にエキサイティングです。静的initを実行する)、静的ローダーロックのデッドロックにつながる可能性があります:-) –

1

、関数にローカルな静的変数の初期化がアトミックであるとスレッドセーフなので、はい、コードのあなたの行は、スレッドセーフであると -

編集8.5.2実質的に同等。 (構文上、最初のバージョンではコピーコンストラクタが必要ですが、コンパイラはそれを生成しません)。

しかし、ファクトリ関数にどのような引数が提供されるのか、どこから取り出されるのかは不明です。

+0

スレッドセーフである* namespace scope *で静的変数の初期化について章と節を引用できますか? §6.7[stmt.dcl] p4:「宣言文」はスレッドセーフですが、ブロックスコープの宣言にのみ適用されると思います。 (言い換えれば、関数内の静的宣言)。あなたができるなら、それは素晴らしいことでしょう。 –

+0

@MartinBonner、名前空間のスコープについては何も言いたくありませんでした。この質問の文脈は、関数スコープの静的なものです。 100%明確になることが明確になります。 – SergeyA

+0

私は質問にそれを読んでいませんでしたが、再読、私はあなたが正しいと思います。しかし、後でこの質問をGoogleから見つけた他の人々のために、重要な注意点があります。 –

1

variable_type variable_name = initializerは、常に初期設定であり、デフォルトの構成および割り当てではありません。 【dcl.init]/15は、15.3(例外処理、

形態

T x = a; 

並びに引数の受け渡し、関数の戻り値、例外をスロー(15.1)でで発生する初期化を有しています)、集約メンバ初期化(8.5.1)はコピー初期化と呼ばれます。 [注:コピー初期化は移動を呼び出すかもしれません(12.8)。 -end note]

関連する問題