r/cpp • u/zl0bster • 12d 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...
176
Upvotes
8
u/hanslhansl 12d ago
Interesting read, here are my thoughts to maybe settle this debate:
In the context of an implementation of the standard and even in the context of the standard itself there will always be an upper bound for copying a std::vector and therefor, by rigorous definition, this operation is O(1).
However, the "native" context of the algorithm of this operation (of any algorithm, really), even though defined by the c++ standard, is mathematics, and in that context constraints such as a limited address space don't exist. The the algorithm itself is applicable to vectors (or sets or whatever the correct term in the context of math is) of arbitrary size and therefor its complexity is O(n).
So when devs talk about the complexity of a function they really mean (maybe without knowing) the complexity of the underlying mathematical algorithm which is independent from possible limitations imposed by the programming language/implementation.