yohhoyの日記

技術的メモをしていきたい日記

std::stringとゼロ初期化

C++標準ライブラリの文字列型std::string*1リテラル0を用いた初期化に関するメモ。
2021-07-02追記:C++2b(C++23)に向けてP2166R1が採択され、nullptr_tを取るstd::stringstd::string_viewコンストラクタはdelete宣言される。この仕様追加によって本記事にあるs1, s2, s3はいずれもコンパイルエラーとして検出される。

#include <string>
std::string s1 = 0;    // NG: 未定義動作
std::string s2(0);     // NG: 未定義動作
std::string s3 = (0);  // NG: 未定義動作
std::string s4{0};     // OK: 空文字列""で初期化
std::string s5 = {0};  // OK: 空文字列""で初期化
  • s1, s2, s3ではコンストラクbasic_string(const char*, const A& = A())が選択され、第1引数にはヌルポインタが渡されるためライブラリ要件違反により未定義動作(undefined behavior)を引き起こす。
  • s4, s5ではオーバーロード解決において初期化子リスト・コンストラクタが最も優先されるため*2、コンストラクbasic_string(initializer_list<char>, const A& = A())が選択され、その引数にchar型の初期化子リスト{ '\0' }が渡されて空文字列""による初期化が行われる。

C++11(N3337) 21.4.2/p9, p16より引用。

basic_string(const charT* s, const Allocator& a = Allocator());
9 Requires: s shall not be a null pointer.

basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
16 Effects: Same as basic_string(il.begin(), il.end(), a).

関連URL

*1:正確には std::basic_string クラステンプレート。

*2:C++11(N3337) 13.3.1.7