6 ms·
In C++ if the string is a rvalue reference you could std::move it into part of the return value. Think a signature like template<typename T> std::pair<
by missblit 12y ago
In C++ if the string is a rvalue reference you could std::move it into part of the return value. Think a signature like
template<typename T>
std::pair<std::string, std::vector<std::string_view>>
tokenize_string(T &&str);
This would be efficient when the user passes a temporary, and it would be safe.
Which isn't to say the Rust solution isn't totally cool. Being able to easily check this class of errors at compile time is probably a lot nicer than needing to learn all the relatively complicated parts that would go into a easy to use / safe /efficient / still slightly weird C++ solution.
- eridius 12y agoSure, and then somewhere along the way you throw away the first element of the pair, because you're not using it, but you're still using the views, and oops you just reintroduced the bug you tried to fix. Which is to say, yes, you can obviously write C++ code that works. But you run the risk that one tiny mistake, or a change weeks, months, or years later, causes memory issues. Being able to completely rule out this class of error at compile-time is really amazingly useful.
- missblit 12y agoYes I agree completely. I was thinking about that after I wrote my comment, the code is only safe relative to the original sample, and it's only a band-aid for the lack of more comprehensive lifetime guarantees. Of course you can jump through more hoops, by encapsulating the string, string_view data in a proper class. But when there's tradeoffs between safety and convenience, there's a point where people will understandingly choose convenience.
- ajross 12y agoThat's a forest for the trees argument. The ability to introduce bugs ("make a tiny mistake") in future changes is an inherent property of software, and you can't fix this in the general case. Rust just fixes this for the case of free-memory-read bugs. That has value, but it's a much more limited scope than you're implying. Really I think this is the biggest problem with Rust. The stuff broken about C++ isn't really its memory model, it's simply its complexity. And every time I look at what's happening in Rust I see the same kind of complexity being introduced at every turn. I mean seriously: "named lifetime parameters"? And the syntax is a bare single quote? That's a joke, right? No one but Rust nerds is going to grok this, and real code needs to me maintained by mediocrities. Frankly Go seems to have this "don't introduce new nonsense" problem under much better control, so if I need to pick a horse in the race, it's that one, not Rust.
- Ygg2 12y agoAs a mediocrity, I think you are making a big fuss about it. Yes. Lifetimes are hard. Yes, it requires lots of compiler wrestling. However Rust compiler gives pretty good hints what lifetimes should be added and deduces lifetimes in few simple cases. Additionally you can opt out if if you are willing to allocate more memory.
- eridius 12y agoThis comment is a joke, right? I find it hard to believe that any programmer would say "the compiler prevents me from writing broken code? That's too complex!" Yes, a proper typing system involves more visible moving parts than a broken typing system. But a proper typing system is vastly more powerful. C++ may not have lifetimes, but every time I touch C++ I have to be really careful that I don't accidentally introduce memory or threading bugs, because they're both really easy to do. Someone who's programmed C++ for a long time might not even realize it, but then again, the vast majority of C++ code in this world almost certainly contains numerous memory and threading bugs. And why the comparison to Go? Go doesn't live in the same world as Rust. It's not a systems programming language. At this point it's mostly a glorified web server application language. And if you're going to pick Go because of the lack of memory lifetime issues, you may as well pick any other garbage-collected language out there.
- ajross 12y agoAgain, forest for the trees. Your laser focus on one particular type of bug blinds you to the fact that complex systems lead to bugs in general. I'm not interested in defending C++ (or Go, or anything else). I'm saying I see Rust falling down the same "cool new ideas" rabbit hole as C++, and Haskell, and Erlang, and Common Lisp, and... Of those languages only one has achieved any notable success. And btw: the idea of calling something a "systems programming language" that can't even make a system call is laughable. Can I mmap a buffer to pass to a hardware video codec or make an ioctl to an audio driver in rust? Guess which language I can do that in? If "Go doesn't live in the same world as Rust", then Rust isn't in the same galaxy as C/C++.
- 12y ago
- pfultz2 12y agoActually, it should be written more like this: template<typename T> std::pair<T, std::vector<std::string_view>> tokenize_string(T &&str); So then it uses `std::forward` to conditionally move the string for rvalues, and `T` will be a reference to the original string for lvalues.