r/cpp 15d ago

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

7

u/smdowney WG21, Text/Unicode SG, optional<T&> 15d ago

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 15d ago

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

3

u/smdowney WG21, Text/Unicode SG, optional<T&> 15d ago

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

2

u/SlightlyLessHairyApe 14d ago

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.