⛓️
[C++] <ranges>のviewを見る2 - single_view
single_view
single_view<T>
は型T
の要素を1つだけ持つシーケンスを作成するViewです。
#include <ranges>
int main() {
std::ranges::single_view<int> sv{20};
for (int n : sv) {
std::cout << n; // 1度だけ呼ばれる
}
}
これもまたrangeを取るアルゴリズムに対してあえて1要素のrangeを入れたい場合など、1要素シーケンスが欲しい時に活用できるでしょう。
これは次のように定義されます。
namespace std::ranges {
template<copy_constructible T>
requires is_object_v<T>
class single_view : public view_interface<single_view<T>> {
private:
semiregular-box<T> value_; // 説明専用メンバ変数
public:
single_view() = default;
constexpr explicit single_view(const T& t);
constexpr explicit single_view(T&& t);
template<class... Args>
requires constructible_from<T, Args...>
constexpr single_view(in_place_t, Args&&... args);
constexpr T* begin() noexcept;
constexpr const T* begin() const noexcept;
constexpr T* end() noexcept;
constexpr const T* end() const noexcept;
static constexpr size_t size() noexcept;
constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
};
}
single_view
もまた、contiguous range(イテレータがcontiguous iteratorの範囲)です。
4つ目のコンストラクタはT
のオブジェクトを内部でin place構築するためのものです。args...
にコンストラクタ引数を渡す事で、直接コンストラクタを呼んで構築することができます。
int main() {
// std::stringのコンストラクタを呼び出してもらう
std::ranges::single_view<std::string> sv(std::in_place, "in place construct", 8);
for (auto& str : sv) {
std::cout << str; // in place
}
}
range factories
single_view
にもrange factoryとなる関数オブジェクトが用意されています。これを用いると幾分か記述を省略できます。
int main() {
for (auto& str : std::views::single(std::string{"in place construct", 8})) {
std::cout << str;
}
}
このstd::view::single
はカスタマイゼーションポイントオブジェクトであり、std::view::single(arg)
のように呼び出すとstd::ranges::single_view{arg}
を構築して返してくれます(無論、引数は完全転送されます)。
ただし、このCPOは1引数しか受け付けないため、in placeコンストラクタを呼び出すことはできません。
Discussion