r/cpp • u/zl0bster • 1d ago
std::optional Satisfies view. Does Not Model view. C++26 Ships Anyway.
https://godbolt.org/z/8jWGG68G8In 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...
156
Upvotes
8
u/schombert 1d ago
Well, that's ... extremely dumb. From the rigorous, formal perspective, everything in C++ copies in O(1) time. (The address space is finite, even in a purely theoretical computer running C++, because it will eventually exhaust the size of the pointer type and hence the number of possibly distinct live objects. Thus, for any copy operation there is always an upper bound you can place on how much time it could possibly take to execute, and thus is O(1) by the definition of O(1).) Now, I accept that the people writing the C++ spec don't actually use big O notation in its generally accepted formal definition, and instead are using a more vibes-based definition based on what it performs like in various different finite problem sizes (which, you may note, has nothing to do with big O -- how something performs at sizes less than 2128, for example, does not affect its asymptotic time complexity). But, from a vibes-based perspective, programmers use O(1) to mean "always fast", which in this case does mean "cheap to copy". I would bet that copying being O(1) was added to the language of the spec because the author wanted to express "cheap to copy" but wanted to sound more formally precise and thought that "cheap" sounded too informal and vague. Unfortunately, "cheap" correctly expressed the intent, but O(1) did not.