constexpr basic_string_view() noexcept; // (1)
constexpr basic_string_view(
const basic_string_view&) noexcept = default; // (2)
constexpr basic_string_view(const CharT* str); // (3)
basic_string_view(nullptr_t) = delete; // (4) C++23
constexpr basic_string_view(const CharT* str, size_type len); // (5)
template <class It, class End>
constexpr basic_string_view(It begin, End end); // (6) C++20
template <class R>
constexpr explicit basic_string_view(R&& r); // (7) C++23
概要
- (1) : デフォルトコンストラクタ。空の
basic_string_view
オブジェクトを構築する - (2) : コピーコンストラクタ。コピー元と同じ文字列を参照する
- (3) : 文字配列を受けとって、その文字配列の全体(ただしヌル文字を含む場合はそこまで)を参照する
- (5) : 文字配列と長さを受けとって、文字配列
str
の先頭len
文字を参照する - (6) : 文字のイテレータ範囲
[begin, end)
を参照する - (7) : 文字のレンジ
R
を参照する
テンプレートパラメータ制約
- (6) :
It
はcontiguous_iterator
の要件を満たすことEnd
はsized_sentinel_for<It>
の要件を満たすことis_same_v<iter_value_t<It>, charT>
がtrue
であることis_convertible_v<End, size_type>
がfalse
であること
- (7) :
R
はコンセプトranges::contiguous_range
およびranges::sized_range
のモデルであることis_same_v<ranges::range_value_t<R>, charT>
がtrue
であることis_convertible_v<R, const charT*>
がfalse
であることd
をremove_cvref_t<R>
型の左辺値としたとき、d.operator ::std::basic_string_view<charT, traits>()
が妥当な式ではないこと
事前条件
- (3) : 範囲
[str, str + Traits::length(str))
が妥当であること (アクセス可能であること) - (5) : 範囲
[str, str + len)
が妥当であること - (6) :
- 範囲
[begin, end)
が妥当であること It
がcontiguous_iterator
のモデルであることEnd
がsized_sentinel_for<It>
のモデルであること
- 範囲
効果
メンバ変数として、参照する文字配列へのポインタをconst CharT* data_
、文字数をsize_type size_
があるものとして、
- (1) :
data_ = nullptr;
およびsize_ = 0;
とする - (3) :
data_ = str;
およびsize_ = Traits::length(str);
とする - (5) :
data_ = str;
およびsize_ = len;
とする - (6) :
data_ = to_address(begin);
およびsize_ = end - begin;
とする - (7) :
data_ = ranges::data(r);
およびsize_ = ranges::size(r);
とする
計算量
- (1), (5) : 定数時間
- (3) : 文字数に対して線形時間
例外
- (7) :
ranges::data(r)
およびranges::size(r)
が投げた例外
備考
basic_string_view
のコンストラクタにtemplate<size_t N>basic_string_view(const charT (&str)[N])
タイプの配列を受け取るコンストラクタが無いのは次の使い方をしたときstr
のサイズがsizeof(buf)
となり、それは利用者の意図しない挙動になる可能性が高いと判断されたからである。
char buf[128];
snprintf(buf, sizeof(buf), "abc");
string_view str(buf);
- ヌル文字を含む文字列リテラル全体から
basic_string_view
を構築したい場合はstd::string_view_literals::svリテラル
を用いる。
例
#include <cassert>
#include <iostream>
#include <string_view>
#include <vector>
int main()
{
// (1)
// デフォルト構築
{
std::string_view sv;
assert(sv.data() == nullptr);
assert(sv.size() == 0);
}
// (2)
// コピーコンストラクタ。コピー元と同じ文字列を参照する
{
std::string_view base{"Hello World"};
std::string_view sv = base;
std::cout << "(2) : " << sv << std::endl;
}
// (3)
// 文字配列を受けとって参照するコンストラクタ
{
std::string_view sv = "Hello World";
std::cout << "(3) : " << sv << std::endl;
}
// (5)
// 文字配列と文字数を受けとって部分文字列を参照するコンストラクタ
{
// "Hello World"の先頭5文字"Hello"を参照
std::string_view sv{"Hello World", 5};
std::cout << "(5) : " << sv << std::endl;
}
// (6)
// 文字のイテレータ範囲を受け取って参照するコンストラクタ
{
std::string s = "Hello World";
std::string_view sv{s.begin(), s.begin() + 5};
std::cout << "(6) : " << sv << std::endl;
}
// (7)
// contiguous_rangeからの構築
{
std::vector vec = {'H', 'e', 'l', 'l', 'o', '\0', '!'};
// 参照するのは入力範囲先頭からそのサイズ(`std::ranges::size()`)分
std::string_view sv{vec};
std::cout << "(7) : " << sv << std::endl;
// explicitのため、このような初期化や暗黙変換は無効
//std::string_view sv = {vec};
}
}
出力
(2) : Hello World
(3) : Hello World
(5) : Hello
(6) : Hello
(7) : Hello!
バージョン
言語
- C++17
処理系
- Clang: 4.0 (5以外) ✅
- GCC: 7.1 (5以外) ✅, 10.1 ✅
- ICC: ??
- Visual C++: ??
参照
- ISO/IEC JTC1 SC22 WG21 N3762
- P1391R4 Range constructor for
std::string_view
- C++20での、イテレータ範囲版コンストラクタ追加
- P2166R1 A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr.
- C++23での、
nullptr_t
をとるコンストラクタのdelete宣言追加
- C++23での、
- P1989R2 Range constructor for
std::string_view
2: Constrain Harder- C++23での、レンジ版コンストラクタ追加
- P2499R0
string_view
range constructor should beexplicit
- LWG Issue 3857.
basic_string_view
should allow explicit conversion when only traits vary