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_view2: Constrain Harder- C++23での、レンジ版コンストラクタ追加
- P2499R0
string_viewrange constructor should beexplicit - LWG Issue 3857.
basic_string_viewshould allow explicit conversion when only traits vary