basic_string
substr(size_type pos = 0,
size_type n = npos) const; // (1) C++03
constexpr basic_string
substr(size_type pos = 0,
size_type n = npos) const; // (1) C++20
constexpr basic_string
substr(size_type pos = 0,
size_type n = npos) const &; // (1) C++23
constexpr basic_string
substr(size_type pos = 0,
size_type n = npos) &&; // (2) C++23
概要
部分文字列を取得する。
pos
番目からn
要素の文字列を返す。
引数省略時は、先頭位置(0
番目)から全要素(npos
)の文字列を返す。
要件
pos <= size()
戻り値(C++20まで)
n
とsize() - pos
のうち、小さい方をコピーする長さrlen
として、
basic_string(data()+pos, rlen)
を返す。パラメータn
のデフォルト引数であるnpos
の場合には、pos
番目以降の全体を返す。
効果(C++23から)
- (1) 次と等価 :
return basic_string(*this, pos, n);
- (2) 次と等価 :
return basic_string(std::move(*this), pos, n);
例外
pos > size()
の場合、out_of_range
例外を送出する。
備考
C++23から(2)右辺値修飾オーバーロードの追加にともない、従来からある(1)はconst左辺値参照オーバーロードに変更される。
同時にメンバ関数substr
のライブラリ仕様記述は、新たに追加されたbasic_string
コンストラクタを用いて書き直される。その後でも基本的な動作はC++20までと同一であるが、(2)のオーバーロードでは右辺値のstd::string
からの部分文字列切り出しが効率化(余計なコピー/アロケーションの削減)される。
例
#include <iostream>
#include <string>
int main()
{
const std::string s = "hello";
// 2番目から3要素だけ抜き出した部分文字列を取得する
{
std::string result = s.substr(2, 3);
std::cout << result << std::endl;
}
// 2番目以降の全体からなる部分文字列を取得する
{
std::string result = s.substr(2);
std::cout << result << std::endl;
}
}
xxxxxxxxxx
#include <iostream>
#include <string>
int main()
{
const std::string s = "hello";
// 2番目から3要素だけ抜き出した部分文字列を取得する
{
std::string result = s.substr(2, 3);
std::cout << result << std::endl;
}
// 2番目以降の全体からなる部分文字列を取得する
{
std::string result = s.substr(2);
std::cout << result << std::endl;
}
}
出力
llo
llo
C++23の右辺値参照修飾オーバーロード追加後の変更例
#include <iostream>
#include <string>
// 右辺値stringを返す関数
auto f() -> std::string;
int main()
{
std::string s = "some long string that forces allocation";
// sから部分文字列のstringをコピーして作成、sは変更されない(この振る舞いは変わらない)
std::string result1 = s.substr(5, 4);
// C++20 : 一時オブジェクトのstringから部分文字列のstringをコピーして作成
// C++23 : 一時オブジェクトのstringのリソースを再利用して部分文字列を保持するstringオブジェクトを作成
std::string result2 = f().substr(5, 4);
// C++20 : 一時オブジェクトのstringから部分文字列のstringをコピーして作成
// C++23 : 一時オブジェクトのstringのリソースを再利用して部分文字列を保持するstringオブジェクトを作成
std::string result3 = std::string("hello").substr(5, 4);
// C++20 : sから部分文字列のstringをコピーして作成、sは変更されない
// C++23 : sのリソースを再利用して部分文字列を保持するstringオブジェクトを作成、aは有効だが未規定な状態となる(C++23における動作変更)
std::string result4 = std::move(s).substr(5, 4);
}
参照
- P0980R1 Making
std::string
constexpr - P2438R2
std::string::substr() &&
- C++23での(2)右辺値修飾オーバーロード追加