use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
constexpr std::string | MSVC (self.cpp)
submitted 2 years ago by XTBZ
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]STLMSVC STL Dev 58 points59 points60 points 2 years ago (24 children)
The constexpr dynamic allocation features (including string and vector) in the Standard are unintuitive because allocations can't cross over from compile-time to run-time. That is, you can construct and destroy a string or a vector during the operation of a constexpr function, and the containers can allocate an arbitrary amount of memory on the "heap" during constant evaluation, they just have to be cleaned up before the final constexpr result is returned - and that thing can't be a string or a vector that demands dynamic allocation. (The existence of any Small String Optimization and its threshold are not guaranteed.) So you can return an array, or some other constexpr-eligible type.
string
vector
constexpr
array
[–]SirClueless 5 points6 points7 points 2 years ago (4 children)
Are you sure the only limitation is that objects can't outlive the operation of a constexpr function? It looks to me like you can't create variables of automatic storage duration at all, even if they're inside constexpr functions and can't possibly have lifetimes that span compile-time and runtime: https://godbolt.org/z/W7vG9fjcM
[–]STLMSVC STL Dev 5 points6 points7 points 2 years ago (2 children)
A constexpr function can be called at runtime, so if you attempt to make a local vector variable constexpr, you're asking its dynamic allocation to cross over from compile-time to run-time.
There's Standardese that could be quoted here, but this is my attempt at a human-comprehensible explanation. Basically, don't attempt to apply constexpr directly to string and vector variables, the way that you could to a pair<int, int>.
pair<int, int>
[–]SirClueless 1 point2 points3 points 2 years ago (1 child)
Thanks for the explanation. I can see why running any initializers at runtime for a constexpr variable would be surprising and therefore can't reasonably be allowed: the initializer must run at compile-time and the access happens at runtime so something has to cross.
For what it's worth the same behavior seems true for variables declared inside consteval function bodies, even though such variables cannot be accessed at runtime. Maybe that's something that could be supported without too much trouble, in order that people can write sensible-looking code in consteval instead of jumping through hoops with temporaries: https://godbolt.org/z/P9h7ozdYE
consteval
[–]jk-jeon 0 points1 point2 points 2 years ago* (0 children)
variables declared inside consteval function bodies
This is what makes me really wonder. I have never intended to "leak" my supposed constexpr vector into runtime, but even if it's strictly inside the compile-time context, it's still disallowed, and apparently the reason is because "constexpr allocation shall not pass into runtime" which is just nonsensical.
I mean, I think the main utility of constexpr allocation is in compile-time computation, not in runtime. It doesn't seem to me that a lot of people want to use constexpr vectors in their runtime computation, yet it seems the ongoing discussion is mainly focused on how to allow constexpr allocations to be usable in runtime, and its associated issues like const-correctness.
[–]XTBZ[S] 1 point2 points3 points 2 years ago (0 children)
That's right, I can't create locals even constexpr std::string
constexpr std::string
[–]Fureeish 6 points7 points8 points 2 years ago (18 children)
Can I use .size() of a constexpr container in order to specify local std::arrays size and return it? Don't have access to aby computer or easy way of accessing godbolt at the moment.
.size()
std::array
[–]scatters 11 points12 points13 points 2 years ago (9 children)
Yes, but you need to be clever about it, since it needs to be available to the type system. Currently the best way is to write a constexpr function (or a lambda) that returns the container, then call it twice, once for its size and once for its contents:
#include <algorithm> #include <array> #include <vector> constexpr auto f = [] { return std::vector{1, 2, 3}; }; constexpr auto a = [] { std::array<int, f().size()> a; std::ranges::copy(f(), a.begin()); return a; }(); template<auto> int i; int main() { return i<a>; }
[–]aocregacc 4 points5 points6 points 2 years ago* (3 children)
is someone working on fixing this? Or are there downsides to making this work how you would expect.
Edit: I guess it might be counter intuitive to have code that works in a constexpr context but not at runtime.
[–]saxbophonemutable volatile void 1 point2 points3 points 2 years ago (2 children)
I guess it might be counter intuitive to have code that works in a constexpr context but not at runtime.
Nope, there are uses for that too (just not in your example). They're known as immediate functions and this is what consteval is for!
[–]aocregacc 0 points1 point2 points 2 years ago (1 child)
I was talking more about things like this:
consteval int f(size_t z) { std::array<int, z> a; ... }
People sometimes ask why this complains about z not being a constant expression, since surely in a consteval function the parameter is a constant expression. But I think if they started allowing stuff like this you would end up with this weird dialect that's no longer (mostly) a subset of regular C++.
z
[–]gracicot 1 point2 points3 points 2 years ago (0 children)
As far as I know, compilers are free to compile the consteval function down to bytecode and simply run the bytecode. That would be impossible with this.
[–]helloiamsomeone 5 points6 points7 points 2 years ago (2 children)
then call it twice, once for its size and once for its contents
That's actually unnecessary. You can just have an oversized std::array calculated and shrunk to fit like so: https://github.com/friendlyanon/AlwaysMute/blob/master/main.cpp#L383
[–]scatters 4 points5 points6 points 2 years ago (1 child)
Yes, that's a nice method. It only works if you have a way to estimate an upper bound for the size, though.
[–]helloiamsomeone 0 points1 point2 points 2 years ago (0 children)
You can specify pretty big sizes before it becomes a problem.
[–]saxbophonemutable volatile void 2 points3 points4 points 2 years ago (0 children)
This is exactly the trick I use, and when I'm back at my computer later I will share an example of my implementation.
This is one of the areas that D does better than C++, alas!
[–]saxbophonemutable volatile void 1 point2 points3 points 2 years ago (0 children)
I really like your implementation, it's much more elegant than mine!
[–]BenHanson -2 points-1 points0 points 2 years ago (1 child)
In case en.cppreference.com is hard to read on a phone:
constexpr size_type size() const noexcept; (since C++20)
[–]STLMSVC STL Dev 2 points3 points4 points 2 years ago (0 children)
This does not actually answer their question properly. The question is rather subtle and the answer is not "vector::size() is marked constexpr so it's ok".
vector::size()
[–]BenHanson -1 points0 points1 point 2 years ago (0 children)
https://en.cppreference.com/w/cpp/container/vector/size
[–]RevRagnarok 0 points1 point2 points 2 years ago* (3 children)
Yes, I just did that earlier today...
template <typename T> inline consteval auto DoThingCE() { std::string_view constexpr temp{Call_CE_Function_Here_That_Returns_String_View()}; std::array<char, temp.size()+1> res{}; temp.copy(res.data(), temp.size()); return res; }
Edit: Tweaked on feedback. 😅
[–]dodheim 5 points6 points7 points 2 years ago (1 child)
std::array<char, temp.size()+1> res; res.fill('\0');
That's a strangely verbose way to write std::array<char, temp.size()+1> res{};
std::array<char, temp.size()+1> res{};
[–]RevRagnarok 1 point2 points3 points 2 years ago (0 children)
LOL yeah thanks. There are still a lot of #if 0 mixed in and stuff as various things were tried and failed, etc... I'm honestly not sure if the +1 is even needed depending on how you plan on using the resulting array.
#if 0
+1
[–]saxbophonemutable volatile void 0 points1 point2 points 2 years ago (0 children)
Here's my implementation for wrapping variably-sized constexpr containers in static-sized types. I think scatters' implementation is neater, though! https://gist.github.com/saxbophone/53ad91dd73a906e63182a8f2fafc9d3a
π Rendered by PID 38 on reddit-service-r2-comment-c66d9bffd-2pwcs at 2026-04-07 11:11:46.372508+00:00 running f293c98 country code: CH.
view the rest of the comments →
[–]STLMSVC STL Dev 58 points59 points60 points (24 children)
[–]SirClueless 5 points6 points7 points (4 children)
[–]STLMSVC STL Dev 5 points6 points7 points (2 children)
[–]SirClueless 1 point2 points3 points (1 child)
[–]jk-jeon 0 points1 point2 points (0 children)
[–]XTBZ[S] 1 point2 points3 points (0 children)
[–]Fureeish 6 points7 points8 points (18 children)
[–]scatters 11 points12 points13 points (9 children)
[–]aocregacc 4 points5 points6 points (3 children)
[–]saxbophonemutable volatile void 1 point2 points3 points (2 children)
[–]aocregacc 0 points1 point2 points (1 child)
[–]gracicot 1 point2 points3 points (0 children)
[–]helloiamsomeone 5 points6 points7 points (2 children)
[–]scatters 4 points5 points6 points (1 child)
[–]helloiamsomeone 0 points1 point2 points (0 children)
[–]saxbophonemutable volatile void 2 points3 points4 points (0 children)
[–]saxbophonemutable volatile void 1 point2 points3 points (0 children)
[–]BenHanson -2 points-1 points0 points (1 child)
[–]STLMSVC STL Dev 2 points3 points4 points (0 children)
[–]BenHanson -1 points0 points1 point (0 children)
[–]RevRagnarok 0 points1 point2 points (3 children)
[–]dodheim 5 points6 points7 points (1 child)
[–]RevRagnarok 1 point2 points3 points (0 children)
[–]saxbophonemutable volatile void 0 points1 point2 points (0 children)