std::ranges::views::concat, std::ranges::concat_view

出自cppreference.com
 
 
範圍庫
範圍適配器
 
 
在標頭 <ranges> 定義
template< ranges::input_range... Views >
    requires (ranges::view<Views> && ...) && (sizeof...(Views) > 0) &&
              /*concatable*/<Views...>
class concat_view
    : public ranges::view_interface<concat_view<Views...>>
(1) (C++26 起)
namespace views {
    inline constexpr /* 未指定 */ concat = /* 未指定 */;
}
(2) (C++26 起)
調用簽名
template< ranges::viewable_range... Rs >
    requires /* 见下文 */
constexpr ranges::view auto concat( Rs&&... rs );
(C++26 起)
輔助類型別名
template< class... Rs >
using /*concat-reference-t*/ =
    ranges::common_reference_t<ranges::range_reference_t<Rs>...>;
(3) (僅用於闡述*)
template< class... Rs >
using /*concat-value-t*/ = std::common_type_t<ranges::range_value_t<Rs>...>;
(4) (僅用於闡述*)
template< class... Rs >
using /*concat-rvalue-reference-t*/ =
    ranges::common_reference_t<ranges::range_rvalue_reference_t<Rs>...>;
(5) (僅用於闡述*)
輔助概念
template< class Ref, class RRef, class It >
concept /*concat-indirectly-readable-impl*/ = /* 见描述 */;
(6) (僅用於闡述*)
template< class... Rs >
concept /*concatable*/ = /* 见描述 */;
(7) (僅用於闡述*)

concat_view 表現為一個 view 工廠,它接受任意數量的範圍和一個實參列表,其所提供的視圖開始於首個範圍的首個元素並結束於最末範圍的最末元素,其間的所有範圍元素都按照實參中給出的相應順序排列,相當於將各實參範圍拼接到一起。

1) 此類模板有一個 view 的非空包模板形參,其中每一個都至少實現 input_range 且為 concatable (7)
2) views::concat 是一個定製化點對象。

給定子表達式包 exprs,表達式 views::concat(exprs...)

  • exprs 是只包含一個元素的包,並且該元素的類型實現了 input_range表達式等價views::all(exprs...)
  • 否則表達式等價於 concat_view(exprs...)
3) 代表引用類型。需要一項額外約束以保證每個底層範圍的 ranges::range_reference_t 都可以轉換為 ranges::common_reference_t
4) iterator::value_type,它還額外關注各底層範圍的 value_type,以支持底層範圍具有代理迭代器的情況。
5) 右值引用,它還正確地支持底層迭代器定製了 iter_move 的情況。
6) 針對 iterator 定義了 indirectly-readable 概念,以使 concat_view 可以實現 input_range
等價於:
template< class... Rs >
concept /*concat-indirectly-readable*/ = // 仅用于阐述
    std::common_reference_with</*concat-reference-t*/<Rs...>&&,
                               /*concat-value-t*/<Rs...>&> &&
    std::common_reference_with</*concat-reference-t*/<Rs...>&&,
                               /*concat-rvalue-reference-t*/<Rs...>&&> &&
    std::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...>,
                                         ranges::iterator_t<Rs>> && ...);
其中僅用於闡述的概念 /*concat-indirectly-readable-impl*/
template< class Ref, class RRef, class It >
concept /*concat-indirectly-readable-impl*/ = // 仅用于阐述
    requires(const It it) {
        { *it } -> std::convertible_to<Ref>;
        { ranges::iter_move(it)} -> std::convertible_to<RRef>;
    };
7) 確定任意兩個或更多的不同範圍是否可以被適配為一個自身實現了範圍的序列。等價於:
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...>;

concat_view 總是實現 input_range,且當所適配的每個 view 類型都實現 forward_rangebidirectional_rangerandom_access_rangesized_range 時也實現相應的概念。

當最末底層範圍實現 common_rangeconcat_view 可以是 common_range

定製點對象

名字 views::concat 代表一個定製點對象,它是某個字面 semiregular 類類型的 const 函數對象。 細節參見定製點對象 (CustomizationPointObject)

數據成員

成員 描述
std::tuple<Views...> views_ 所有適配的視圖對象
(僅用於闡述的成員對象*)

成員函數

構造 concat_view
(公開成員函數) [編輯]
返回指向起始的迭代器
(公開成員函數) [編輯]
返回 指向末尾的迭代器或哨位
(公開成員函數) [編輯]
返回元素數,僅當底層(適配的)範圍滿足 sized_range 時才提供
(公開成員函數) [編輯]
繼承自 ranges::view_interface
返回視圖是否為空,僅當視圖滿足 forward_range 時提供
(std::ranges::view_interface<D> 的公開成員函數) [編輯]
(C++23)
返回指向範圍起始的常量迭代器
(std::ranges::view_interface<D> 的公開成員函數) [編輯]
(C++23)
返回對應於範圍常量迭代器的哨位
(std::ranges::view_interface<D> 的公開成員函數) [編輯]
返回派生視圖是否為非空,僅當 ranges::empty 可應用於它時提供
(std::ranges::view_interface<D> 的公開成員函數) [編輯]
返回派生視圖中的首元素,僅當視圖滿足 forward_range 時提供
(std::ranges::view_interface<D> 的公開成員函數) [編輯]
返回派生視圖中的末元素,僅當視圖滿足 bidirectional_rangecommon_range 時提供
(std::ranges::view_interface<D> 的公開成員函數) [編輯]
返回派生視圖中的第 n 個元素,僅當視圖滿足 random_access_range 時提供
(std::ranges::view_interface<D> 的公開成員函數) [編輯]

推導指引

嵌套類

類名 定義
迭代器類型
(僅用於闡述的成員類模板*)

輔助模板

沒有針對 concat_viewranges::enable_borrowed_range 特化,因為它要求它的迭代器的實現中從始至終包含所有底層範圍的所有迭代器和哨位的副本。

註解

沒有實參的 views::concat() 是非良構的,因為不存在確定一種元素類型 T 的合理方法。單個實參的 views::concat(r) 表達式等價於 views::all(r)

功能特性測試 標準 功能特性
__cpp_lib_ranges_concat 202403L (C++26) std::ranges::concat_view

示例

初步版本可以在 Compiler Explorer 上測試。

#include <cassert>
#include <list>
#include <print>
#include <ranges>
#include <vector>

int main()
{
    std::vector<int> v0{1, 2, 3}, v1{4, 5};
    int a[]{6, 7};
    int i{8};
    auto ie{std::views::single(i)};
    
    auto con = std::views::concat(v0, v1, a, ie);
    assert(con.size() == v0.size() + v1.size() + std::size(a) + ie.size());
    std::println("con.size():{}", con.size());
    std::println("con:{}", con);
    con[6] = 42; // con 是 random_access_range, operator[] 返回引用
    assert(a[1] == 42); // 经由 con[6] 改动 a[1]
    std::println("con:{}", con);
    
    std::list<int> l{7, 8}; // list 是双向范围
    auto cat = std::views::concat(v0, l);
    std::println("cat:{}", cat);
    // cat[0] = 13; // 编译时错误:cat 是双向的 => 没有 operator[]
}

輸出:

con.size():8
con:[1, 2, 3, 4, 5, 6, 7, 8]
con:[1, 2, 3, 4, 5, 6, 42, 8]
cat:[1, 2, 3, 7, 8]

引用

  • C++26 標準(ISO/IEC 14882:2026):
  • 26.7.18 Concat view [range.concat]

參閱

由拉平 range 組成的 view 所獲得的序列構成的 view
(類模板) (範圍適配器對象) [編輯]
由拉平範圍組成的視圖並以分隔符間隔所獲得的序列構成的 view
(類模板) (範圍適配器對象) [編輯]
到被適配視圖的對應元素的引用元組組成的 view
(類模板) (定製點對象) [編輯]
計算各適配視圖的 n 元笛卡爾積所得的元組組成的 view
(類模板) (定製點對象) [編輯]