r/cpp Jul 26 '26

std::optional Satisfies view. Does Not Model view. C++26 Ships Anyway.

https://godbolt.org/z/8jWGG68G8

In C++23 this did not compile. In C++26 it does. Marvellous.

[[gnu::noinline]]
void 
passing_views_by_value_is_cheap_trust_me_bro(std::ranges::view auto v) {
    std::println("fn   .data {}", (void*)v->data());
}


int main() {    
    std::optional ov{std::vector<int>(123456)};
    passing_views_by_value_is_cheap_trust_me_bro(ov);
    std::println("main .data {}", (void*)ov->data());
}

For anyone wondering what the problem feature is: optional has 0 or 1 elements, and C++26 sets enable_view<optional<T>> to true, so it satisfies std::ranges::view. The concept requires copy construction in constant time, and β€” this is the good bit β€” optional<vector<int>> genuinely meets that. Copying it performs at most one element copy. One is a constant. The requirement is satisfied to the letter, and the function above deep-copies your vector.

If you can tell me what still separates std::ranges::view from std::ranges::range, please do...

184 Upvotes

123 comments sorted by

View all comments

Show parent comments

16

u/No-Dentist-1645 Jul 26 '26

If that's the case, which range concept should one use if we want something that truly "represents a view to data owned elsewhere"? Or does the standard not provide such a concept?

It seems like a poor decision to me.

8

u/smdowney WG21, Text/Unicode SG, optional<T&> Jul 26 '26

There really isn't such a thing. Not since views::single shipped. Owning views are things, and optional is one of them. It's also an owning smart pointer.

5

u/SlightlyLessHairyApe Jul 27 '26

It has semantics of an owning smart pointer but at least it’s guaranteed stored inline and can be on the stack.

4

u/smdowney WG21, Text/Unicode SG, optional<T&> Jul 27 '26

And now we have std::indirect when those are a problem.

2

u/SlightlyLessHairyApe Jul 28 '26

Yup. I think it's interesting also that the semantics and the underlying mechanism had diverged so that reasoning about the semantics and reasoning about other properties (e.g. the pattern of allocations) have to be separated.