namespace std::ranges {
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0) && concatable<Views...>
class concat_view : public view_interface<concat_view<Views...>> { …… }; // (1)
namespace views {
inline constexpr /*unspecified*/ concat = /*unspecified*/; // (2)
}
}
概要
concat_viewは複数のRangeを連結し、1つのRangeとするview。
- (1):
concat_viewのクラス定義 - (2):
concat_viewを生成するカスタマイゼーションポイントオブジェクト(Rangeアダプタオブジェクトではない)
Rangeコンセプト
| borrowed | sized | output | input | forward | bidirectional | random_access | contiguous | common | viewable | view |
|---|---|---|---|---|---|---|---|---|---|---|
| (1) | 〇 | 〇 | (2) | (3) | (4) | (5) | ○ | ○ |
- (1): 連結するすべてのRangeが
sized_rangeのとき - (2): 連結するすべてのRangeが
forward_rangeのとき - (3): 連結するすべてのRangeが
bidirectional_rangeであり、少なくとも最後のRange以外がcommon_rangeのとき - (4): 連結するすべてのRangeが
random_access_rangeであり、少なくとも最後のRange以外がcommon_rangeのとき - (5): 最後のRangeが
common_rangeのとき
テンプレートパラメータ制約
連結するすべてのビューに対して、
- それらの要素に共通の値型
Cv、参照型Cr、右辺値参照型Crrが存在し、 Cr&&とCv&、Cr&&とCrr&&、Crr&&とCv const&にそれぞれ共通の参照型があり、- 連結するすべてのビューのイテレータ
itについて、*itがCrに変換可能であり、ranges::iter_move(it)がCrrに変換可能であること。
効果
- (2): 式
views::concat(Es...)の効果は次の通りEs...が1要素で、その型がinput_rangeのモデルであるとき、decltype((Es...[0]))(Es...[0])(その要素自身)と等しい- それ以外のとき、
concat_view(Es...)と等しい
備考
このビュー(およびviews::concatアダプタ)は、フリースタンディング処理系でも使用できる。
本説明に用いる説明専用要素を以下のように定義する。
namespace std::ranges {
template<class... Rs>
using concat-reference-t = common_reference_t<range_reference_t<Rs>...>;
template<class... Rs>
using concat-value-t = common_type_t<range_value_t<Rs>...>;
template<class... Rs>
using concat-rvalue-reference-t = common_reference_t<range_rvalue_reference_t<Rs>...>;
template<class Ref, class RRef, class It>
concept concat-indirectly-readable-impl =
requires (const It it) {
{ *it } -> convertible_to<Ref>;
{ ranges::iter_move(it) } -> convertible_to<RRef>;
};
template<class... Rs>
concept concat-indirectly-readable =
common_reference_with<concat-reference-t<Rs...>&&, concat-value-t<Rs...>&> &&
common_reference_with<concat-reference-t<Rs...>&&, concat-rvalue-reference-t<Rs...>&&> &&
common_reference_with<concat-rvalue-reference-t<Rs...>&&, concat-value-t<Rs...> const&> &&
(concat-indirectly-readable-impl<concat-reference-t<Rs...>, concat-rvalue-reference-t<Rs...>, iterator_t<Rs>> && ...);
template<class... Rs>
concept concatable = requires {
typename concat-reference-t<Rs...>;
typename concat-value-t<Rs...>;
typename concat-rvalue-reference-t<Rs...>;
} && concat-indirectly-readable<Rs...>;
// Fs を Rs の末尾を除いたパックとする
template<bool Const, class... Rs>
concept concat-is-random-access =
all-random-access<Const, Rs...> &&
(common_range<maybe-const<Const, Fs>> && ...);
template<bool Const, class... Rs>
concept concat-is-bidirectional =
all-bidirectional<Const, Rs...> &&
(common_range<maybe-const<Const, Fs>> && ...);
}
メンバ関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
(constructor) |
コンストラクタ | C++26 |
begin |
先頭を指すイテレータを取得する | C++26 |
end |
番兵を取得する | C++26 |
size |
要素数を取得する | C++26 |
reserve_hint |
要素数の近似値を取得する | C++26 |
継承しているメンバ関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
empty |
Rangeが空かどうかを判定する | C++26 |
operator bool |
Rangeが空でないかどうかを判定する | C++26 |
front |
先頭要素への参照を取得する | C++26 |
back |
末尾要素への参照を取得する | C++26 |
cbegin |
定数イテレータを取得する | C++26 |
cend |
定数イテレータ(番兵)を取得する | C++26 |
operator[] |
要素へアクセスする | C++26 |
推論補助
| 名前 | 説明 | 対応バージョン |
|---|---|---|
(deduction_guide) |
クラステンプレートの推論補助 | C++26 |
例
#include <vector>
#include <array>
#include <ranges>
#include <print>
int main() {
std::vector<int> v1{1, 2, 3}, v2{4, 5}, v3{};
std::array a{6, 7, 8};
auto s = std::views::single(9);
std::print("{} ", std::views::concat(v1, v2, v3, a, s));
}
出力
[1, 2, 3, 4, 5, 6, 7, 8, 9]
バージョン
言語
- C++26
処理系
- Clang: 23 ✅
- GCC: 15 ✅
- Visual C++: 2022 Update 14 ❌
参照
- 26.7.18 Concat view (2024-08-10)
- P2542R8 views::concat
- LWG Issue 4076.
concat_viewshould be freestanding- C++26で、このビューがフリースタンディング処理系に対応した
- LWG Issue 4082.
views::concat(r)is well-formed whenris anoutput_range- C++26で、単一の
input_rangeを渡した場合のviews::concatがviews::allではなくその要素自身を返すよう変更され、output_rangeに対しても適格となった
- C++26で、単一の