C++1z(C++17)標準ライブラリの文字列型std::basic_string<charT>
クラステンプレートでは、ポインタ型charT*
を返す 非const版 data
メンバ関数が追加される。(ポインタ型const charT*
を返すconst版data
メンバ関数はC++98から存在している。)
まとめ:
- C++98/03標準ライブラリでは仕様による保証が無いものの、実用上は
&buf[0]
を利用できる。*1 - C++11/14標準ライブラリでは
&buf[0]
を利用する。 - C++1z標準ライブラリでは
&buf[0]
またはbuf.data()
を利用する。
下記例のようなレガシーAPIに対して、配列の代わりに
std::string
オブジェクトを文字列取得バッファとして渡す方法。// バッファsにNUL終端文字列を取得(size=バッファ長) // 戻り値:バッファに格納された文字数(NUL文字を除く) int legacy_get_string_api(char *s, int size);(略)
// C++11準拠標準ライブラリ #include <string> std::string buf(BUFSIZE, '\0'); int len = legacy_get_string_api( &buf[0], BUFSIZE ); // OK buf.resize(len);文字列取得バッファとしてのstd::string
C++1z準拠の標準ライブラリでは、&buf[0]
の他にbuf.data()
という記述も可能となる。
// C++1z(C++17)準拠標準ライブラリ #include <string> std::string buf(BUFSIZE, '\0'); int len = legacy_get_string_api( buf.data(), BUFSIZE ); // OK buf.resize(len);
2021-02-03追記:正式なC++17ライブラリ仕様ではLWG 2475修正が適用され、std::basic_string<charT>
内部バッファのNUL終端文字位置へのNUL終端文字上書きに限って特例許容される。詳細はyumetodoさんによる こちらの記事 を参照のこと。
ただしNUL終端文字が配置される文字位置*2に関しては、C++14以前と同様に書き換えが禁止されることに注意。
一方C++11標準規格によれば、文字位置
文字列取得バッファとしてのstd::string0≦n<size()
ならばstring
オブジェクト外部から書き換え可能だが、NUL終端文字が格納されているn=size()
位置は書き換えが禁止される。
提案文書P0272R0より該当箇所を引用(下線部は強調)。
charT* data() noexcept;
Returns: A pointerp
such thatp + i == &operator[i]
for eachi
in[0,size()]
.
Complexity: Constant time.
Requires: The program shall not alter the value stored atp + size()
.
関連URL
- P0272R0 Give 'std::string' a non-const '.data()' member function.
- std::stringの地味な拡張 - yohhoyの日記
- dataメンバ関数と戻り値ポインタ型のconst性 - yohhoyの日記
- C++標準文字列:c_str, data, operator[] - yohhoyの日記
- cppreference std::basic_string::data
*1:Herb Sutter氏によるコメント:"Short answer: In practice, on every implementation I know, std::string’s contents are contiguous and null-terminated."
*2:厳密に表現するならば、c_str() メンバ関数のために文字列末尾へ自動配置されるNUL終端文字の位置となる。std::string s("abc\0xyz"); の s[3] 位置のように、明示的に配置したNUL終端文字は自明に書き換えが可能。