This is what people mean when they say template metaprogramming is dumb. It's like Rube-Goldberg software development, you're trying to do something conceptually so simple, but jump through insane hoops to get there.
Well done solving this puzzle, but I’m left in shock. The need to employ a template, static constexpr variables, a lambda function, and four utility functions just to compile-time generate a static string in C++ is an embarrassment. What decisions brought us to this point? How will we explain ourselves to our children?
That constexpr is spellt conteval. Good lord this is grinding my gears. Ten years ago I thought constexpr would fix this but we had to invent ANOTHER const statment because the word "may" screws with people. I can accept constinit, even argue that we should have it in the C20 standard. But ugh this makes my head hurt.
IIRC the committee didn't have time to find/evaluate a solution to make dynamically allocated memory inside a constexpr context available at run time before C++20 has to be shipped. I don't know why this wasn't fixed in C++23 though, but maybe again by lack of time because of the pandemic.
@@benjaminnavarro865 But I thought something put on the heap automatically doesn't make it runtime? Right now compilers just either? Or is this in regards to pointer arguments?
@@cppweekly Do you know why? Or at least have the paper number, I'm curious to know if the proposal wasn't technically sound or if the committee is waiting on a revision or something for it to happen
“Nice”? You think this is nice? This is four non-obvious functions and a template to generate a static string. This is a complete travesty! Can’t anybody see that the emperor isn’t wearing anything?
@@a314that's not the point of the video. He could have used 1+1 instead, to demonstrate compile time programing. Instead he chose to make something interesting enough he could showcase a corner case. And if he used a pragma to print at compile time it would have also worked
If the compiler is not going to create the 10MB array, why not make the array as big as std::string's max size so that we know it is big enough instead of some arbitrary size?
Now, forgive me, dementia has been knocking at my door for some time, now. My understanding went like this: Consts are important because they eliminate the use of 'magic numbers' while retaining the immutability of literals. Constexpr goes one better by showing our work that came up with that immutable value. That obviously is erroneous, something like 80% of this channel wouldn't be about constexpr, if it were correct. Will somebody kindly give me a hint were I turned two pages at the same time? I am afraid by 20 minutes into the video, I started hearing my irascible professor complaining about over egging the pudding. I am grateful for the challenge though.
Its because some idiot said a constexpr "may" be compile time. Not "should" or "will be" that it "might". Because of that the compiler can/will dance around your code till your pc locks up with a 2 terabyte dump file or, aka, the looping constexpr lamba. The consteval is supposed to be a poison pill that makes this all simpler (as shown in the video), However, to be honest, I am not sure what the output "should" be? If I make a program that tells the compiler to either make 10megs of data, or produce a file with 10megs of data, but don't use it, what should its output be?
Still a WIP, but tested on every platform that allows it: github.com/lefticus/tools plus a conglomeration of other constexpr-related tools I've needed over the years.
that's very good. I arrived at a similar solution while trying to do compile-time string formatting, but I didn't know the callable trick so my user code has to pass parameters as template values from the start. With this callable route, i think I can refactor my code to be nicer for the user
Also, why prefer lambda arguments over nontype template parameters? The inputs to both are always constexpr for this pattern. I often use template parameter list as a replacement for normal function parenthesized list when the parameter needs to be used/provided as constexpr
Orders of magnitudes of bytes should always be powers of 2 (thus making the invention of "mebi", "kibi", etc. obsolete). One megabyte == 1,408,576 bytes. Power to the pedants! ETA: This is also how we get screwed out of SSD storage, e.g.
A while back I wrote a library to replace boost::format (I'm pretty sure this was pre-std::format adoption), because I found that boost's parsing was slow enough to justify my choice through profiling for this application. The replacement used a preprocessor + template library I found online to make and process strings at compile time, and it converted a given string into a type that would directly convert the provided data without any runtime parsing of format specifiers. So you'd say something like hax::format("blah %d ") % value, and that would generate code that was basically std::puts("blah "); hax::put_signed_decimal_int(value); std::puts(" "); constexpr has come along so well that I suspect rewriting this library could actually be a fun challenge.
Cool! I think you could pass make_data as a template parameter to to_string_view instead of as a normal parameter. In this way, I think the compiler could probably do even less work at compile time (of course, at runtime, it is already minimal)
I was going to aesthetics with usability, but to your point, then it might be possible to pass a lambda with captures, since the captures would now be part of the NTTP.
Indeed, the idea of mixing compile time metaprogramming with conventional c++ data structures has too many implications. I'd rather see a clean compile time only mode/environment for this.
You can't make the size really dynamic, because then you would have to evaluate everything twice again. However, you could make the size a template parameter so you can provide the upper limit for each call individually. And if you happen to pass a string that's too big you'll get some sort of compiler error because std::copy would run into UB and UB is disallowed in a compile time context. Of course you could also just use an assertion or check the size yourself and throw an exception if the string is too big, the compiler will halt and tell you when it reaches a throw statement.
I don't understand why function make_static() makes things static. Could you please link the annotation that appears in 22:35? I can't seem to find it.
@@verylongtrain but why? I can understand that when you create a class using template it's definition has to exist and if this definition required storing those parameters then surely they should be static, but why would you have to store data that was only passed to a function?
eel.is/c++draft/temp.param#8 "An id-expression naming a non-type template-parameter of class type T denotes a **static** storage duration object of type const T, known as a template parameter object"
Cool stuff! I'm guessing if your oversized array buffer too small it'll just give you a compile time error. Maybe could be a template argument. *shurgs*
Yes, it will result in a compile-time error. it *might* be possible to do a compile-time retry logic with if constexpr, but I'm not 100% sure about that.
And I failed. I know things are happening at compile time but I can’t convince the compiler in all the places it matters. It’d work if the parameters of consteval functions were constexpr.
Note that in the version I implemented (as a function) you get different behavior if it's a primitive (not static) or a user defined type. If you do a constexpr template variable instead, as others have said, you get consistent behavior.
Interesting, I didn't know about p2647. It appears to have just been approved for C++23. It looks like it will solve this problem and work exactly as expected. github.com/cplusplus/papers/issues/1318
Presumably the difficulty lies in moving dynamically allocated memory out of constexpr land.. what if we wrote a completely constexpr allocator (a simple stack allocator using a static array for example) and fed that to std::string. Would that work?
That was one of the original solutions proposed for making the containers constexpr capable. It might work again today. I was thinking about trying to write my own constexpr capable PMR adapter to test with.
You can take for example a std::vector from compile time to runtime world as std::array, but do you think it is possible right now to get a std::vector into an std::array?
This is definitely doable, but takes several steps. github.com/lefticus/tools/blob/main/test/static_views_tests.cpp#L138-L147 I have gotten some level of map -> static data working.
interesting video as always! im glad to see from other comments here though that im not the only one to say something like: a small piece of my soul died while watching this video. i know it feels awesome for the hero who figures out a hack like this, but can we also still acknowledge that overall this is awful, not awesome. that is to say, clearly there is a shortcoming in the language that should be addressed so that people can accomplish the things they set out to accomplish in a normal way.
I tried to solve Advent of Code 2021 at compile time, and is was a mess (but in most cases, it worked). A library would have been super helpful. I think this December, I'll embrace CTRE (compile time regular expressions) and non-type template parameters. Thank you so much for pointing out these techniques!
Hmm, this would all be so much simpler if there were a way to distinguish between memory leaked at compile time and memory that you just want translated into e.g. rodata for runtime. Maybe constexpr on a variable could signify that? but then how do you tell what memory belongs to that variable? very tough issue
Originally the proposal for constexpr new/delete was going to automatically create static data in objects that "leaked" to compile time. However, they couldn't agree on that feature. Which as you point out, is a complicated question.
@@cppweekly I've thought more on this, and I've thought that _maybe_ the constexpr engine could run the destructor of the object, see if all the memory allocated in that expression is freed, and then sorta roll back that destruction. But then that brings up issues of const-ness, like if a unique_ptr is stored as a constexpr variable, it itself would be const but would the data it points to be? I would lean towards yes it would have to be but that might break the semantics of a const unique_ptr. Maybe only unique_ptr could be stored as a constexpr variable? Very tricky
std::string is much easier to work with in many ways. The goal is to figure out how to make the code easy to work with with fewer human made decisions at compile time.
why are you specifying the return value of 'to_string_view' with '->' instead of replacing the 'auto' return type? I thought you only should use the '->' when using 'decltype'
It's just a style choice. auto func(); // fully compile-time deduced auto func() -> auto; // same as above decltype(auto) func(); // "perfect returning" compile-time deduction auto func() -> decltype(auto); // same as above auto func() -> std::string_view; // trailing return type. this is the same for lambdas: [](){ /*return something*/ } // let the compiler deduce the return type []() -> auto { /*... */} // pointless but valid []() -> std::string_view { /*...*/ } // the only way to specify the return type of a lambda.
Oh good lord. Because constexpr has the word "may" in it meant we get 10 years of this till consteval. Even if msvc dies when it try's to move a god damn pointer from the C++ domain to C, atleast it does consteval right in c++20.
That's great thanks. I already need this. I also need the string type to be any string-like type and the string view type to be any string_view-like type. Count me in if you wanted to make this a library. I'm gonna be using it in my own framework anyway 😅. Thanks. It's a combination of great techniques.
yes should be fully C++20 capable. The two-step process (oversized->right sized, followed by static-constexpr) can work in C++17, if you have some other kind of stack-based runtime sized data.
@@iamjadedhobo If one day YT goes down then that URL won't work. And the humanity will go extinct if this code plays a huge role in a serious project lol.
I'm not sure the oversized array is necessary. Within the make function it's no worse to make an oversized array AND THEN fix it than it is to get the right size the first time (check size first, instantiate array)
I think its cool that you found this solution but it still seems like a hack to me. That is a lot of work to just get a constexpr string, I pray that somehow this will get handled better in the future
Weren't all these new c++ additions suppose to help the developer? I'm getting more and more confused. You really cannot learn C++ unless you know all kind of weird tricks...
Exactly the problem that had been searching for a solution for a while. However this is still disgusting and not satisfying. There should be a much simpler way to do this really. This is an embarrassing scenario in 2022.
The distinction was introduced by harddisk vendors to sell undersized drives. If you bought 1K memory chips there were for sure 1024 bits (or bytes depending on chip type) in that chip. An 2716 EPROM was a 16Kbit device containing 16384 memory bits. HD vendors could swindle you out of a few Mbytes of storage on a Gb size advertised device if they could make you accept their "SI" units deception.
@@iamjadedhobo hard disk vendors today sell storage in SI units and not in the binary powers not because of some conspiracy to cut costs but because the actual usable space is below the binary bytes value. You can’t actually fill up a 1GB hard drive with 2^30 bytes of information. A portion of that has to be reserved for the storage formatting. Some of it for the device’s background processes. A distinction between these two types of prefixes are important because a lot of computing power would go into physical processes. You wouldn’t want missile guidance systems to mess up just because the computer guy wants k to mean an even 1024 right? Besides, it’s an extra letter away as a prefix and has the same number of syllables when read out loud.
@@fromgermany271 you can do both? Which is pretty much in the spirit of C++ anyway. We go from top level systems all the way down to the bare metal level. From the main point all the way into the side details. C++ programmers aren’t afraid to discuss any aspect.
This solves a problem Ive been having for quite a while as well but looking at it still hurts my soul
This is what people mean when they say template metaprogramming is dumb. It's like Rube-Goldberg software development, you're trying to do something conceptually so simple, but jump through insane hoops to get there.
I kind of like the poison pill approach they went with on consteval. Now lets see if gcc will properly tell you what line that consteval is on:P
No it's just a poor implementation of it. It's fine in Rust. I don't know why the foundation is rushing features.
Well done solving this puzzle, but I’m left in shock. The need to employ a template, static constexpr variables, a lambda function, and four utility functions just to compile-time generate a static string in C++ is an embarrassment.
What decisions brought us to this point? How will we explain ourselves to our children?
That constexpr is spellt conteval. Good lord this is grinding my gears. Ten years ago I thought constexpr would fix this but we had to invent ANOTHER const statment because the word "may" screws with people. I can accept constinit, even argue that we should have it in the C20 standard. But ugh this makes my head hurt.
IIRC the committee didn't have time to find/evaluate a solution to make dynamically allocated memory inside a constexpr context available at run time before C++20 has to be shipped. I don't know why this wasn't fixed in C++23 though, but maybe again by lack of time because of the pandemic.
@@benjaminnavarro865 But I thought something put on the heap automatically doesn't make it runtime? Right now compilers just either? Or is this in regards to pointer arguments?
Yes, there was a proposal to move a compile-time dynamic allocation into static memory automatically, but it didn't get through.
@@cppweekly Do you know why? Or at least have the paper number, I'm curious to know if the proposal wasn't technically sound or if the committee is waiting on a revision or something for it to happen
Only elite programmers working in the language full time for their entire life are able to use it. 5y for a string. This leads to madness
"This is unteachable." - Bjarne Stroustrup
Wow, crazy! I had given up on this already. I thought there was no way of solving this problem! Thanks so much!
Very nice! Hopefully these issues can be smoothed out in future standards
“Nice”? You think this is nice? This is four non-obvious functions and a template to generate a static string. This is a complete travesty!
Can’t anybody see that the emperor isn’t wearing anything?
Maybe I'm being a little masochistic, but I think this is a beautiful solution. Love that you were able to figure this out!
This is the stuff I am subscribed for! Thank you very much, this exact problem has annoyed me for quite some time and I really like this solution.
One more step toward C++ being able to apply Normal order evaluation (lazy evaluation), at least, at compile time! Great stuff, thank you Jason!
OMG! You can do this in D in 2 lines. For sure C++ is creating jobs!
import std.range: repeat, join;
pragma(msg, "hello world, ".repeat(3).join);
C++, a language that has complicated solutions for trivial problems. Enjoy!
Is that D statement executed at compile time?
@@vanjazed7021 yes, indeed
@@a314that's not the point of the video. He could have used 1+1 instead, to demonstrate compile time programing. Instead he chose to make something interesting enough he could showcase a corner case. And if he used a pragma to print at compile time it would have also worked
If the compiler is not going to create the 10MB array, why not make the array as big as std::string's max size so that we know it is big enough instead of some arbitrary size?
Turns out the size of the "big enough" array has a huge impact on MSVC compile times. So it's not quite as flexible as I thought.
Now, forgive me, dementia has been knocking at my door for some time, now. My understanding went like this: Consts are important because they eliminate the use of 'magic numbers' while retaining the immutability of literals. Constexpr goes one better by showing our work that came up with that immutable value. That obviously is erroneous, something like 80% of this channel wouldn't be about constexpr, if it were correct. Will somebody kindly give me a hint were I turned two pages at the same time? I am afraid by 20 minutes into the video, I started hearing my irascible professor complaining about over egging the pudding. I am grateful for the challenge though.
Its because some idiot said a constexpr "may" be compile time. Not "should" or "will be" that it "might". Because of that the compiler can/will dance around your code till your pc locks up with a 2 terabyte dump file or, aka, the looping constexpr lamba. The consteval is supposed to be a poison pill that makes this all simpler (as shown in the video), However, to be honest, I am not sure what the output "should" be? If I make a program that tells the compiler to either make 10megs of data, or produce a file with 10megs of data, but don't use it, what should its output be?
Good stuff Jason. Looking forward to trying out the new library.
Still a WIP, but tested on every platform that allows it: github.com/lefticus/tools plus a conglomeration of other constexpr-related tools I've needed over the years.
Meanwhile, in D:
import std.range : repeat, join;
pragma(msg, "hello world, ".repeat(3).join);
Yes, at compile-time.
that's very good. I arrived at a similar solution while trying to do compile-time string formatting, but I didn't know the callable trick so my user code has to pass parameters as template values from the start. With this callable route, i think I can refactor my code to be nicer for the user
Check this out also: devblogs.microsoft.com/cppblog/how-we-used-cpp20-to-eliminate-an-entire-class-of-runtime-bugs/
@@cppweekly very interesting. Also very cool use of std::type_identity
Also, why prefer lambda arguments over nontype template parameters? The inputs to both are always constexpr for this pattern. I often use template parameter list as a replacement for normal function parenthesized list when the parameter needs to be used/provided as constexpr
I want to be pedantic about it, so I'll point out that the array was originally 10 megabytes, then it was changed to 10 mebibytes.
Yeah, no. OG Megabyte 4 lyfe.
Thank you 🙏
I came here looking for this comment, and was not disappointed.
Orders of magnitudes of bytes should always be powers of 2 (thus making the invention of "mebi", "kibi", etc. obsolete). One megabyte == 1,408,576 bytes. Power to the pedants!
ETA: This is also how we get screwed out of SSD storage, e.g.
bro. its time to leave the basement
A while back I wrote a library to replace boost::format (I'm pretty sure this was pre-std::format adoption), because I found that boost's parsing was slow enough to justify my choice through profiling for this application. The replacement used a preprocessor + template library I found online to make and process strings at compile time, and it converted a given string into a type that would directly convert the provided data without any runtime parsing of format specifiers. So you'd say something like hax::format("blah %d
") % value, and that would generate code that was basically std::puts("blah "); hax::put_signed_decimal_int(value); std::puts("
"); constexpr has come along so well that I suspect rewriting this library could actually be a fun challenge.
The NTTP as a conxtexpr static variable trick still blows my mind.
Cool! I think you could pass make_data as a template parameter to to_string_view instead of as a normal parameter. In this way, I think the compiler could probably do even less work at compile time (of course, at runtime, it is already minimal)
I was going to aesthetics with usability, but to your point, then it might be possible to pass a lambda with captures, since the captures would now be part of the NTTP.
This kind of stuff makes me think C++ will be replaced by a better tool.
Indeed, the idea of mixing compile time metaprogramming with conventional c++ data structures has too many implications. I'd rather see a clean compile time only mode/environment for this.
c++ needs to be killed with fire and start all the way over from scratch
Can the hard-coded 10MiB be changed to a dynamic value based on the input string? Or would a bigger string at least fail compilation?
It will fail at compile time. I should probably make the limit into a compile-time template parameter.
You can't make the size really dynamic, because then you would have to evaluate everything twice again. However, you could make the size a template parameter so you can provide the upper limit for each call individually. And if you happen to pass a string that's too big you'll get some sort of compiler error because std::copy would run into UB and UB is disallowed in a compile time context. Of course you could also just use an assertion or check the size yourself and throw an exception if the string is too big, the compiler will halt and tell you when it reaches a throw statement.
I'd imagine there's some SFINAE magic one could incant to fall back to doing the work twice (thrice?) if it overflows on the first attempt
I don't understand why function make_static() makes things static. Could you please link the annotation that appears in 22:35? I can't seem to find it.
Basically because when you pass a string as a template parameter, it has to exist statically.
@@verylongtrain but why?
I can understand that when you create a class using template it's definition has to exist and if this definition required storing those parameters then surely they should be static, but why would you have to store data that was only passed to a function?
eel.is/c++draft/temp.param#8
"An id-expression naming a non-type template-parameter of class type T denotes a **static** storage duration object of type const T, known as a template parameter object"
Cool stuff! I'm guessing if your oversized array buffer too small it'll just give you a compile time error. Maybe could be a template argument. *shurgs*
Yes, it will result in a compile-time error. it *might* be possible to do a compile-time retry logic with if constexpr, but I'm not 100% sure about that.
Laughing in D.
import std.stdio;
string rept(string s, int n){
string ret;
for(int i=0;i
I’m at 4:10, and I’m not going to watch the rest right now. Because I think I can do it and want to give it a shot myself before seeing your solution.
And I failed. I know things are happening at compile time but I can’t convince the compiler in all the places it matters. It’d work if the parameters of consteval functions were constexpr.
So template non-type parameter somehow takes memory region for static variables? This is pretty new. Hope that my project moves to C++20 soon.
Note that in the version I implemented (as a function) you get different behavior if it's a primitive (not static) or a user defined type.
If you do a constexpr template variable instead, as others have said, you get consistent behavior.
P2647 allows static constexpr within constexpr. Does it have a *special* meaning when evaluated within a *'real'* constexpr?
Interesting, I didn't know about p2647. It appears to have just been approved for C++23. It looks like it will solve this problem and work exactly as expected. github.com/cplusplus/papers/issues/1318
Presumably the difficulty lies in moving dynamically allocated memory out of constexpr land.. what if we wrote a completely constexpr allocator (a simple stack allocator using a static array for example) and fed that to std::string. Would that work?
That was one of the original solutions proposed for making the containers constexpr capable. It might work again today. I was thinking about trying to write my own constexpr capable PMR adapter to test with.
You can take for example a std::vector from compile time to runtime world as std::array, but do you think it is possible right now to get a std::vector into an std::array?
This is definitely doable, but takes several steps. github.com/lefticus/tools/blob/main/test/static_views_tests.cpp#L138-L147 I have gotten some level of map -> static data working.
@@cppweekly Thanks, I will take a look over it.
interesting video as always! im glad to see from other comments here though that im not the only one to say something like: a small piece of my soul died while watching this video. i know it feels awesome for the hero who figures out a hack like this, but can we also still acknowledge that overall this is awful, not awesome. that is to say, clearly there is a shortcoming in the language that should be addressed so that people can accomplish the things they set out to accomplish in a normal way.
I tried to solve Advent of Code 2021 at compile time, and is was a mess (but in most cases, it worked). A library would have been super helpful. I think this December, I'll embrace CTRE (compile time regular expressions) and non-type template parameters. Thank you so much for pointing out these techniques!
Here's the library: github.com/lefticus/tools/blob/main/include/lefticus/tools/static_views.hpp There's more than just that header.
@@cppweekly thank you very much, and the non promoting ints sound very promising, too!
Why is make_static a consteval function template rather than a static constexpr variable template?
because I had not considered that option when I created it. I have implemented it as an inline constexpr variable template in the library version.
Hmm, this would all be so much simpler if there were a way to distinguish between memory leaked at compile time and memory that you just want translated into e.g. rodata for runtime. Maybe constexpr on a variable could signify that? but then how do you tell what memory belongs to that variable? very tough issue
Originally the proposal for constexpr new/delete was going to automatically create static data in objects that "leaked" to compile time. However, they couldn't agree on that feature.
Which as you point out, is a complicated question.
@@cppweekly I've thought more on this, and I've thought that _maybe_ the constexpr engine could run the destructor of the object, see if all the memory allocated in that expression is freed, and then sorta roll back that destruction. But then that brings up issues of const-ness, like if a unique_ptr is stored as a constexpr variable, it itself would be const but would the data it points to be? I would lean towards yes it would have to be but that might break the semantics of a const unique_ptr. Maybe only unique_ptr could be stored as a constexpr variable? Very tricky
And where is the name of that template parameter object is stored, and how much space that name occupies?
There exists the possibility of symbol table bloat, yes.
Can't you just copy the string literal into a std::array three times without using std::string?
std::string is much easier to work with in many ways. The goal is to figure out how to make the code easy to work with with fewer human made decisions at compile time.
I can't decide if this is awesome or awful. 😁
Why there is (almost) never a link to the source code you are showing. Could save me a lots of time....
This is changing now that all show notes are managed via github. See here github.com/lefticus/cpp_weekly/issues/
Looking forward to the library!
Here's the library: github.com/lefticus/tools/blob/main/include/lefticus/tools/static_views.hpp There's more than just that header.
why are you specifying the return value of 'to_string_view' with '->' instead of replacing the 'auto' return type? I thought you only should use the '->' when using 'decltype'
It's just a style choice.
auto func(); // fully compile-time deduced
auto func() -> auto; // same as above
decltype(auto) func(); // "perfect returning" compile-time deduction
auto func() -> decltype(auto); // same as above
auto func() -> std::string_view; // trailing return type.
this is the same for lambdas:
[](){ /*return something*/ } // let the compiler deduce the return type
[]() -> auto { /*... */} // pointless but valid
[]() -> std::string_view { /*...*/ } // the only way to specify the return type of a lambda.
That's crazy!
Oh good lord. Because constexpr has the word "may" in it meant we get 10 years of this till consteval. Even if msvc dies when it try's to move a god damn pointer from the C++ domain to C, atleast it does consteval right in c++20.
A slight improvement, you forgot about `std::copy_n` 😄
Hmm... I might have to review the code there.
I mean, this is amazing, but this should be solved at the standard so we remove this 'big enough array'
That's great thanks. I already need this. I also need the string type to be any string-like type and the string view type to be any string_view-like type. Count me in if you wanted to make this a library. I'm gonna be using it in my own framework anyway 😅. Thanks. It's a combination of great techniques.
I think this does what you want: github.com/lefticus/tools/blob/main/include/lefticus/tools/static_views.hpp#L74-L80
But what about the terminating mill on the string!
Irrelevant - std::string_view (which is what I want) is not null-terminated.
@@cppweekly Which is super annoying if you want to pass a string_view to a function that accepts a C string (means you have to copy it).
One thing I did not understand is: that works starting on which c++ standard? 23 only?
c++20 and GCC 12, because std::string must be constexpr.
yes should be fully C++20 capable. The two-step process (oversized->right sized, followed by static-constexpr) can work in C++17, if you have some other kind of stack-based runtime sized data.
@@cppweekly Can that process be wrapped cleanly in an operator+ function that can compile-time concatenate two string_view in C++17 ?
I'll wait for the constexpr string.
Now imagine trying to understand this code without any comments in it ;)
Use the URL to this video as a function name :)
@@iamjadedhobo If one day YT goes down then that URL won't work. And the humanity will go extinct if this code plays a huge role in a serious project lol.
I don't understand this video with comments included O_o
I'm not sure the oversized array is necessary. Within the make function it's no worse to make an oversized array AND THEN fix it than it is to get the right size the first time (check size first, instantiate array)
I think its cool that you found this solution but it still seems like a hack to me. That is a lot of work to just get a constexpr string, I pray that somehow this will get handled better in the future
One person's hack is another person's design pattern! 😄
To be honest, I think the source of these problem is "you have to delete the thing you new"
Weren't all these new c++ additions suppose to help the developer? I'm getting more and more confused. You really cannot learn C++ unless you know all kind of weird tricks...
These are esoteric techniques that are highly unlikely to impact normal code.
@@cppweekly Lets hope you're right
I am flabbergasted.
Impressive, but for me more a demonstration C++ is partly "broken". it should be a tool to be productive. Not a tool that fights back.
This feels like a Frankenstein object.
Very nice!
Exactly the problem that had been searching for a solution for a while. However this is still disgusting and not satisfying. There should be a much simpler way to do this really. This is an embarrassing scenario in 2022.
content-addressable static data??? Never would I have presumed such a thing to exist...
This is a huge technique that I used when making this talk: ruclips.net/video/MdrfPSUtMVM/видео.html
10*1024*1024 isn’t 10megabytes right? That’s 10 mebibyte. Mega is an SI term and should mean 10^6.
I'm old
The distinction was introduced by harddisk vendors to sell undersized drives. If you bought 1K memory chips there were for sure 1024 bits (or bytes depending on chip type) in that chip. An 2716 EPROM was a 16Kbit device containing 16384 memory bits. HD vendors could swindle you out of a few Mbytes of storage on a Gb size advertised device if they could make you accept their "SI" units deception.
@@iamjadedhobo hard disk vendors today sell storage in SI units and not in the binary powers not because of some conspiracy to cut costs but because the actual usable space is below the binary bytes value. You can’t actually fill up a 1GB hard drive with 2^30 bytes of information. A portion of that has to be reserved for the storage formatting. Some of it for the device’s background processes. A distinction between these two types of prefixes are important because a lot of computing power would go into physical processes. You wouldn’t want missile guidance systems to mess up just because the computer guy wants k to mean an even 1024 right? Besides, it’s an extra letter away as a prefix and has the same number of syllables when read out loud.
Concentrate on the topic, not on some side areas!
@@fromgermany271 you can do both? Which is pretty much in the spirit of C++ anyway. We go from top level systems all the way down to the bare metal level. From the main point all the way into the side details. C++ programmers aren’t afraid to discuss any aspect.
cool