-1

Consider the following code snippet (full code: https://godbolt.org/z/PMM4z9KvM):

int main() {
    {
        std::cout << "begin std::views::as_rvalue\n";
        auto iss = std::istringstream("12");
        auto is  = std::views::istream<X>(iss);
        auto _   = is | std::views::as_rvalue | std::ranges::to<std::vector>();
        std::cout << "end std::views::as_rvalue\n\n" << std::flush;
    }
    {
        std::cout << "\nbegin my::as_rvalue\n";
        auto iss = std::istringstream("12");
        auto is  = std::views::istream<X>(iss);
        auto _   = is | my::as_rvalue | std::ranges::to<std::vector>();
        std::cout << "end my::as_rvalue\n\n" << std::flush;
    }
}

The output is as follows:

begin std::views::as_rvalue
X()
X(X const&)
X(X&&)
~X()
X(X&&)
X(X&&)
X(X&&)
~X()
~X()
end std::views::as_rvalue

~X()
~X()
~X()

begin my::as_rvalue
X()
X(X&&)
X(X&&)
X(X&&)
~X()
end my::as_rvalue

~X()
~X()
~X()

It seems std::views::as_rvalue has more operations than my::as_rvalue.

Why is std::views::as_rvalue not so cheap as std::move_iterator?

7
  • is | views::as_rvalue equals views::as_rvalue(is) equals ranges::as_rvalue_view(is). Since is is an lvalue, so there is a copy. Commented Aug 4 at 3:11
  • BTW, your AsRvView_ will lead to dangling if the input range is not a borrowed_range. Commented Aug 4 at 3:13
  • It's easy to add a constraint that requires AsRvView_ only accepts borrowed_range. Commented Aug 4 at 7:33
  • But now you rejects vector{...} | views::as_rvalue, or r | views::filter(...) | views::as_rvalue, etc. Commented Aug 4 at 7:34
  • 1
    But v | views::filter(...) | my::as_rvalue will faied even v is lvalue vector, there is nothing to do with owning_view for such cases. Commented Aug 4 at 7:42

1 Answer 1

1

As with all standard range adaptors, std::views::as_rvalue<V> stores a copy of the adapted view V. It's constructor is effectively defined as:

constexpr explicit as_rvalue_view(V base) : base(std::move(base_)) {}

This accounts for the extra copy and move constructions, and destructions.

Sign up to request clarification or add additional context in comments.

1 Comment

base(std::move(base_)) doesn't mean it must copy/move the elements base_ references to.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.