1. ホーム
  2. c++

[解決済み] 中括弧で囲まれたイニシャライザはいつ使うのか?

2023-02-02 05:59:32

質問

C++11では、クラスを初期化するための新しい構文があり、変数を初期化する方法について多くの可能性を与えてくれます。

{ // Example 1
  int b(1);
  int a{1};
  int c = 1;
  int d = {1};
}
{ // Example 2
  std::complex<double> b(3,4);
  std::complex<double> a{3,4};
  std::complex<double> c = {3,4};
  auto d = std::complex<double>(3,4);
  auto e = std::complex<double>{3,4};
}
{ // Example 3
  std::string a(3,'x');
  std::string b{3,'x'}; // oops
}
{ // Example 4
  std::function<int(int,int)> a(std::plus<int>());
  std::function<int(int,int)> b{std::plus<int>()};
}
{ // Example 5
  std::unique_ptr<int> a(new int(5));
  std::unique_ptr<int> b{new int(5)};
}
{ // Example 6
  std::locale::global(std::locale("")); // copied from 22.4.8.3
  std::locale::global(std::locale{""});
}
{ // Example 7
  std::default_random_engine a {}; // Stroustrup's FAQ
  std::default_random_engine b;
}
{ // Example 8
  duration<long> a = 5; // Stroustrup's FAQ too
  duration<long> b(5);
  duration<long> c {5};
}

変数を宣言するたびに、どの初期化構文を使うか考えなければならず、コーディングのスピードが遅くなってしまいます。中括弧を導入したのは、そういう意図ではないのでしょうが。

テンプレートコードの場合、構文を変えると意味が変わってしまうので、正しい方法で行うことが重要です。

どの構文を選べばいいのか、普遍的なガイドラインはないのでしょうか。

どのように解決するのですか?

I を考える は、良いガイドラインになると思います。

  • もし、初期化する(単一の)値が、意図的に 正確な値 を使用する場合は、コピー ( = ) 初期化を使ってください (そうすれば、エラー時に誤って明示的なコンストラクタを起動してしまうことがないからです。一般に、提供された値は異なる解釈をします)。コピー初期化が利用できない場所では、ブレース初期化が正しいセマンティクスを持っているかどうかを確認し、もしそうなら、それを使用します。

  • 初期化する値がリストである場合、そのリストが オブジェクトに格納される (ベクトル/配列の要素や複素数の実部/虚部など)である場合、可能であれば中括弧初期化を使用します。

  • もし、初期化する値が ではなく の値ではなく、格納される を記述します。 というように、オブジェクトの意図する値や状態を表すには、括弧を使用します。例としては vector のファイル名引数、あるいは fstream .