web-dev-qa-db-ja.com

C ++ 20でビューを使用してコンテナーを構築できますか?

範囲は、C++ 20標準バージョンでC++に導入されます。

私の質問:(既存の)標準ライブラリコンテナーを任意の範囲で構築できますか?そしてさらに重要なのは、範囲ビューで?

たとえば、これは:

#include <vector>
#include <iostream>
#include <ranges>

int main() {
    auto sq = [](int x) { return x * x; };
    std::vector<int> vec { 3, 4, 5 };
    std::vector<int> squares { std::ranges::views::transform(vec, sq) };
    for(auto i : squares) { std::cout << i << ' '; }
    std::cout << std::endl;
}

9 16 25を出力する有効なプログラムであるか

これは ranges-v3ライブラリでコンパイル で、その価値があります。

10
einpoklum

私の質問:(既存の)標準ライブラリコンテナーを任意の範囲で構築できますか?そしてもっと重要なのは、範囲ビューで?

いいえ。正しい基準を満たす任意の範囲から構築可能な唯一の標準ライブラリコンポーネントは_std::span<T>_です。

標準ライブラリがおそらく進むであろう方向は、range-v3も向かっている方向です(range-v3からのリンクされた例はコンパイルされますが、非推奨の変換について警告します)- ヘルパー を使用しますあなたのために変換を行うには:

_std::vector<int> squares =
    std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;
_

範囲コンストラクターの方向に進まない理由の1つは、使用しているまさにその例からわかります。

_std::vector<int> squares { std::ranges::views::transform(vec, sq) };
_

その宣言が次の2つとどの程度異なるかを考えてみます。

_std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );
_

vは、単一の_vector<transform_view<...>>_を含む_transform_view_である必要がありますが、wは_vector<int>_です。

さらに、注意深く制約されたコンテナーコンストラクターを標準ライブラリにさらに追加しても、サードパーティのコンテナータイプには役立ちません。ただし、_ranges::to_などの機能は、すべてのケースで完全に機能します。

8
Barry