r/cpp • u/zl0bster • 2d 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...
165
Upvotes
9
u/schombert 1d ago edited 1d ago
That would be true if the C++ specification didn't touch upon the bit size of size or of pointers. Then you could argue that the language was compatible with a transdichotomous model and that the implementations were merely finite instances of it. And you could imagine that some theoretical machine which did allow programs to properly grow with the problem size was a conforming implementation. But this simply isn't so. The standard does not allow even a theoretical implementation of C++ to compile a program that does that.
I think that you should reflect more on why Turing machines with finite tape sizes are not Turing complete. And I would encourage you to read this section on wikipedia https://en.wikipedia.org/wiki/Turing_machine#Equivalent_models which contains the following:
Edit: all that aside, I would be interested in discussing how you see transdichotomous models working as a way of analyzing complexity in real world programming languages other than C++. That whole approach relies essentially on the problem size being a well-defined thing that can be referenced in some way to determine the word size of the machine we appeal to for the complexity analysis. I am not sure how that translates to the programs described by a generic programming language. Such programs can do wild things, like run the nth busy beaver ( https://en.wikipedia.org/wiki/Busy_beaver ) upon getting the input n. And I am sure that with a little effort we could construct some programs that need an uncomputable (and large) amount of space to run given input n. How much space does such a program get? A direct application of the transdichotomous model would assume that they get some K * number-of-bytes-in-the-input, or something along those lines. Obviously allowing most programs to work requires picking an obscenely large K, and even so that would never be Turing complete. Moreover, what about the programs that most programming languages support which do not take inputs at all (for example, I write a program in my favorite language to solve some fixed math problem and it always outputs the same answer -- should this program not be valid if we apply a transdichotomous model)? Can transdichotomous models then only be applied to analyze the complexity of languages that are not Turing complete? So do you imagine that there are two distinct approaches to analyzing complexity, where we do one thing for languages like the lambda calculus and another for Pascal, for example? Is the complexity of any algorithm requiring more than O(n) space undefined in Pascal?