2015-12-23 14 views
20

A POD structにおける構造体はC++ 11でゼロに初期化することができますゼロ再初期化それをゼロに再初期化したいですか?次のように動作します:は、次のようにC++

s = {}; 

誰かが関連する標準語を指摘できますか?

  1. 新しいゼロで初期化されたインスタンスが作成されます。
  2. 新しいインスタンスが既存のインスタンスに割り当てられ、暗黙の代入演算子が呼び出されます。
+1

標準についてはわかりませんが、一部は最適化されている可能性があります。実際には、0を使用しないと、おそらく_all_が最適化されます。 – einpoklum

+1

割り当ての右手にカッコを入れるという明示的なルールがあります。あなたの前提はかなり正しいです。 – chris

+0

「再初期化」のようなものはありません。あなたは何かを一度初期化します。一度だけ。あなたがやっているのは譲渡ですが、微妙ではなく微妙な仕方では非常に異なります。 –

答えて

18

あなたが探していると、[expr.ass]

ブレース-のinit-リストが割り当てへ

  • の右側に表示されることがありますされますスカラーである場合、イニシャライザーリストはせいぜい1つの要素しか持たない。 の意味は、x={v}です。ここで、Tは、式xのスカラー型です。x=T{v}です。 x={}の意味はx=T{}です。
  • クラス・タイプのオブジェクトへの割り当て。この場合、イニシャライザ・リストは、オーバーロード解決(13.5.3,13.3)によって選択された代入演算子関数 の引数として渡されます。

あなたの推測は正しいです。コンパイラは物事を最適化できるかもしれませんが、ゼロ初期化された一時的なものを作成してoperator=に渡すと考えることができます。

12

s = {};は安全ではありません。

問題は、あなたがを希望していることです。s = SomeStruct{};になります。しかし、soperator=then that may be preferred by overload resolutionの別のオーバーロードがあるとします。

これは本当に反パターンです。他のスレッド上で示唆したように、あなたは例えば、関数を書く方がいいでしょう。:

template<typename T> void reset(T &t) { t = T{}; } 

私はあなたにもそう長くsが参照できなかったとして、s = decltype(s){};を書くことができると思います。

+1

あなたの '希望'を明示的に解決に使用してみませんか? 's = SomeStruct {}'?これは 'reset()'への関数呼び出しよりもはっきりしているようです。 –

+1

@ LokiAstariまあ、私たちは 's'の宣言から遠いかもしれないので、これが実際に正しいことを確認するのは簡単ではありません。誤って 's = SomeOtherStruct {}; 'を置くと、他の奇妙な効果が起こる可能性があります。私は間違いの可能性を最小限に抑えるコードパターン(特に明白ではない間違い)を使用しようとしています。私は 'decltype'バージョンが本当に最高だと思います。私はそれを未熟だが、おそらく私の美学を更新する必要があるかもしれない。 –

+0

私は 'SomeOtherStruct {}'についてあなたの意見を述べる。それで 'decltype'の方が意味がありますが、それでもまだ醜いです(そして美学は重要です)。 –