C++ Weekly - Ep 342 - C++20's Ranges: A Quick Start

  Рет қаралды 19,325

C++ Weekly With Jason Turner

C++ Weekly With Jason Turner

Күн бұрын

Пікірлер: 58
@vesk4000
@vesk4000 8 ай бұрын
This is such a cool video! Very useful and to the point! Exactly whay I needed!
@mjKlaim
@mjKlaim 2 жыл бұрын
I remember catching such kind of bugs (from the beginning) in a bunch of unit tests simply by running the test with visual studio Debug mode which also adds iterator checks.
@sheeftz
@sheeftz 2 жыл бұрын
7:33 You used a lamda with a side effect . There is no explicit requirement for the function parameter in ranges::transform not to have side effects, but are you sure that it means it guarantees to call the transformation function object in the expected order and once per object? There is no explicit guarantees of that.
@yogthemuskrat
@yogthemuskrat 2 жыл бұрын
There is no such guarantee. Even more - there is a well known "filter | transform" problem when transform gets called more times that you'd expect.
@sheeftz
@sheeftz 2 жыл бұрын
@@yogthemuskrat Well, then it's broken in the most dangerous way things can be broken in c++. He'd better fix this before people start thinking that lambdas with side effect in views is a smart thing to do.
@cristian-si1gb
@cristian-si1gb 2 жыл бұрын
@@sheeftz Actually, this was always a problem with STL algorithms. See "std::find() is Broken!" by Sean Parent kzbin.info/www/bejne/aHekmmWjg76dfKM&ab_channel=CppCon
@danrobinson2866
@danrobinson2866 11 ай бұрын
I tried the following and expected to see the index values start at 5, that was not the case. for(const auto &[index, elem] : get_data()| std::ranges::views::transform(make_index) | std::ranges::views::drop(5)) { fmt::print("{}: {} ", index, elem); }
@KennyMinigun
@KennyMinigun 2 жыл бұрын
That std::ranges::views is quite a mouthful. I just looked up on cppreference, and bless the creators there is an alias namespace std::views = std::ranges::views.
@TheMR-777
@TheMR-777 2 жыл бұрын
I always define an alias of myself, before using ranges, namespace rg = std::ranges; namespace vs = rg::views; In this way, you can also easily switch b/w std::ranges and range-v3.
@Voy2378
@Voy2378 2 жыл бұрын
@@TheMR-777 I use sv and sr but yeah full namespaces are a bad joke
@oschonrock
@oschonrock 2 жыл бұрын
For the record, after playing around on CE, it turns out that gcc 12.2 with libstdc++ can run the above code (trunk is not required) and clang trunk with libc++ can also run it. So some progress!
@victotronics
@victotronics 2 жыл бұрын
Very nice tutorial. So with that last example you basically have the python "enumerate" iterator. How hard would "zip" be? Is that going to be in 23?
@cppweekly
@cppweekly 2 жыл бұрын
Zip is in 23, yes
@yogthemuskrat
@yogthemuskrat 2 жыл бұрын
There is actually an `enumerate` adapter on Range-V3, btw.
@StephenWarren
@StephenWarren 2 жыл бұрын
See also std::ranges::views::iota, std::ranges::iota_view. iterate_with_index() is basically zip with iota.
@DiegoHavenstein
@DiegoHavenstein 2 жыл бұрын
The transform + make index example is something I tried out recently, but used zip(iota(0), vec) instead. Zip has a special case when 2 args are passed so a std::pair is returned just as in the example from the video
@MohammadJK197
@MohammadJK197 2 ай бұрын
I liked and subscribed within 3min. awesome video. 😛
@sky_is_the_limit_13
@sky_is_the_limit_13 5 ай бұрын
Great video! at @2:16 the primary issue is about the vectors having different memory addresses, even though they contain the same data, right?
@cppweekly
@cppweekly 4 ай бұрын
Correct, we've got the begin() from one vector and the end() from a completely different vector, so we're trying to iterate between two completely unrelated objects.
@oschonrock
@oschonrock 2 жыл бұрын
Doesn't number 3) have lifetime issues as well? Because the ranged for is transformed into a begin() call and then the loop and by then the temporary is gone? Or was that a different scenario, or is now fixed?? Or does the drop view actually save us here, because it extends the lifetime of the temporary vector until we have finished iterating it - because it's lazy. ?
@cristian-si1gb
@cristian-si1gb 2 жыл бұрын
It's safe, the lifetime of the owning_view is extended by __range and begin/end are called on it. auto && __range = range-expression ; auto __begin = begin-expr ; auto __end = end-expr ; for ( ; __begin != __end; ++__begin) { range-declaration = *__begin; loop-statement }
@oschonrock
@oschonrock 2 жыл бұрын
@@cristian-si1gb Thanks. I guess I had that "electric tingling alert" as soon as I saw the "2 step temporary", which is normally what produces this problem. But I guess these views are designed to capture the thing in front of the pipe in some kind of internal reference (that's the "owning" part?), and then, as you say, the view becomes a "one step temporary" which is safely lifetime extended by auto&& __range reference. Is that right?
@cristian-si1gb
@cristian-si1gb 2 жыл бұрын
@@oschonrock All views will by default apply std::views::all on the range they're based on. It's a bit too much to explain in depth here, Tristan Brindle just had a talk explaining why and how this works: kzbin.info/www/bejne/gmHFmY2ma62Aeq8&ab_channel=CppNorth
@VictorHugoVideos
@VictorHugoVideos 2 жыл бұрын
The make_index trick was something that I've always wondered why it didn't existed already.
@ChristianBrugger
@ChristianBrugger Жыл бұрын
I find ranges very exciting. Two problems I struggled with adopting it in my application: * compile times exploding, up to 10 seconds for a single cpp file in both clang and MSVC * very inefficient code generation for some Code I would love to get more deeper insights into this and waiting for someone to cover it. I know sone of it is a quality of implementation problem, but I don't think fully. Some is me using the library in a non optimal way.
@cppweekly
@cppweekly Жыл бұрын
Ranges are complex, so I'm honestly not surprised. But I have not measured it myself. I think in many cases the expressiveness will outweigh the costs.
@alexbalrus
@alexbalrus Жыл бұрын
На первый взгляд сложные конструкции. Почти ничего не понял) Кто-нибудь уже оценил - ranges это действительно замена stl? Есть в них значительная польза?
@literallynull
@literallynull 3 ай бұрын
Используй только то, что упрощает код и делает его читабельнее. Удобно использовать *for (auto& it : std::views::reverse(container))* вместо *for(auto it = container.rbegin(); it != container.rend(); ++it)*
@hammad7829
@hammad7829 8 ай бұрын
how do you type so fast??
@cppweekly
@cppweekly 7 ай бұрын
With fast forward
@c0d3_m0nk3y
@c0d3_m0nk3y 2 жыл бұрын
This is basically the same as LINQ in C#, isn't it?
@OperationDarkside
@OperationDarkside 2 жыл бұрын
Correct me if I'm wrong, but LINQ was supposed to look like SQL but inside C# code. I don't know the C# equivalent, but Java has the streams API, that is kind of similar.
@c0d3_m0nk3y
@c0d3_m0nk3y 2 жыл бұрын
C# LINQ: data .Where(a => a % 2 == 0) .Select(a => a * a) .Take(2); C++20 ranges: data | filter([](const int& a) { return a % 2 == 0; ) | transform([](const int& a) { return a * a; }) | take(2);
@keshkek
@keshkek 2 жыл бұрын
@@c0d3_m0nk3y if you want to use sql like code in c++ you should write DSL which will detect errors etc oni compile time instead of using common code
@DrPastah
@DrPastah 2 жыл бұрын
std::range isn't a thing for C++14 is it?
@ChrisCarlos64
@ChrisCarlos64 2 жыл бұрын
It came with C++20, so no it isn't for C++14
@yogthemuskrat
@yogthemuskrat 2 жыл бұрын
There is range-v3 for that (older versions).
@PaulMetalhero
@PaulMetalhero 2 жыл бұрын
The scripting engine, please!
@cppweekly
@cppweekly 2 жыл бұрын
If only I could drop my contract work and have all of my time to spend on these things!
@billynugget7102
@billynugget7102 2 жыл бұрын
Im not sure about everyone else but a simple for loop with an index (yes this feature does still exist) is much more understandable than what has been presented here. Despite it being more expressive (if you know what is going on) it continues the problem of polluting c++ with more special keywords and libraries that make it less and less accessible than the average enthusiast. “Idiots idolise complexity, a genius strives for simplicity”
@yogthemuskrat
@yogthemuskrat 2 жыл бұрын
A raw loop is easier to understand when it is simple. But with every new condition (like, skip first element, reverse etc.) it gets messier and messier. And it gets not just harder to read but also much more error prone. View adapter on other hand make it easier to follow the "respect the layers of abstraction" principle - that is they strip away all the details of HOW you implement from WHAT you want to do.
@billynugget7102
@billynugget7102 2 жыл бұрын
@@yogthemuskrat bro if you can’t understand for(int i = 1; i
@yogthemuskrat
@yogthemuskrat 2 жыл бұрын
@@billynugget7102 You should add a check, to ensure that container is not empty. A little thing, but it adds verbosity and breaks outside the loop itself.
@hstrauss2214
@hstrauss2214 2 жыл бұрын
A simple for loop with an index might be more understandable, but it is also more restrictive. Just change the vector in the example to a list, an it won't work any more. The presented solution is more general and therefore very much has its justification.
@billynugget7102
@billynugget7102 2 жыл бұрын
@@hstrauss2214 yeah you can justify it that wat but im saying becuase its so clunky many devs will opt for a more simple (and arguably less “expressive”) solution
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
I know it'll never happen, but C++ needs a slice operator. What you just showed with std::ranges::views makes me want to barf.
@valizeth4073
@valizeth4073 2 жыл бұрын
I mean, its not far from many other languages piping operator, like elixirs |>
@spjuanjoc
@spjuanjoc 2 жыл бұрын
Just FYI, with fmt/ranges it should be possible to: //... #include //... fmt::print("{}", get_data() | std::ranges::views::drop(1)); //...
@toRatnesh
@toRatnesh 2 жыл бұрын
This is why sanitizer builds are helpful Compiling with sanitizer (-fsanitize=address) gives error for this auto result = std::all_of(get_data().begin(), get_data().end(), [](const int i){ return i < 5;});
@cppweekly
@cppweekly 2 жыл бұрын
Hmm... I definitely tested with asan and didn't get this error caught, must have used the wrong combination of compiler/tests
@toRatnesh
@toRatnesh 2 жыл бұрын
I was using count_if and for_each instead of all_of and got sanitizer error, so I assumed behavior will be same for all_of but it has different behavior
C++ Weekly - Ep 343 - Digging Into Type Erasure
15:16
C++ Weekly With Jason Turner
Рет қаралды 20 М.
C++ Weekly - Ep 332 - C++ Lambda vs std::function vs Function Pointer
16:30
C++ Weekly With Jason Turner
Рет қаралды 35 М.
Маусымашар-2023 / Гала-концерт / АТУ қоштасу
1:27:35
Jaidarman OFFICIAL / JCI
Рет қаралды 390 М.
Counter-Strike 2 - Новый кс. Cтарый я
13:10
Marmok
Рет қаралды 2,8 МЛН
Caleb Pressley Shows TSA How It’s Done
0:28
Barstool Sports
Рет қаралды 60 МЛН
C++ Weekly - Ep 312 - Stop Using `constexpr` (And Use This Instead!)
18:24
C++ Weekly With Jason Turner
Рет қаралды 53 М.
7 Outside The Box Puzzles
12:16
MindYourDecisions
Рет қаралды 94 М.
C++ Insights - Episode 41: How type-traits work
6:44
Andreas Fertig
Рет қаралды 3,9 М.
How C++ took a turn for the worse
5:03
Code Persist
Рет қаралды 334 М.
C++ Weekly - Ep 350 - The Right Way to Write C++ Code in 2022
16:33
C++ Weekly With Jason Turner
Рет қаралды 40 М.
C++ Weekly - Ep 336 - C++23's Awesome std::stacktrace Library
13:36
C++ Weekly With Jason Turner
Рет қаралды 17 М.
Netflix Removed React?
20:36
Theo - t3․gg
Рет қаралды 60 М.
C++ Weekly - Ep 454 - std::apply vs std::invoke (and how they work!)
13:12
C++ Weekly With Jason Turner
Рет қаралды 11 М.
Arenas, strings and Scuffed Templates in C
12:28
VoxelRifts
Рет қаралды 99 М.