https://www.sandordargo.com/blog/2025/04/23/cpp26-constexpr-language-changes avatar Sandor Dargo's Blog On C++, software development and books * HOME * TAGS * ARCHIVES * BOOKS * SPEAKING * DAILY C++ * HI... * [become_a_p] Blog 2025 04 23 C++26: more constexpr in the core language Post [ ] Cancel C++26: more constexpr in the core language Sandor Dargo Apr 23 2025-04-23T00:00:00+02:00 3 min Since constexpr was added to the language in C++11, its scope has been gradually expanded. In the beginning, we couldn't even use if, else or loops, which were changed in C++14. C++17 added support for constexpr lambdas. C++20 added the ability to use allocation and use std::vector and std::string in constant expressions. In this article, let's see how constexpr evolves with C++26. To be more punctual, let's see what language features become more constexpr-friendly. We'll discuss library changes in a separate article, as well as constexpr exceptions, which need both language and library changes. P2738R1: constexpr cast from void* Thanks to the acceptance of P2738R1, starting from C++26, one can cast from void* to a pointer of type T in constant expressions, if the type of the object at that adress is exactly the type of T. Note that conversions to interconvertible - including pointers to base classes - or not related types are not permitted. The motivation behind this change is to make several standard library functions or types work at compile time. To name a few examples: std::format, std::function, std::function_ref, std::any. The reason why this change will allow many more for more constexpr in the standard library is that storing void* is a commonly used compilation firewall technique to reduce template instantiations and the number of symbols in compiled binaries. P2747R2: constexpr placement new As std::construct_at is a limited tool that only allows to perform value initialization but not others such as default or list initialization, there has been a need to make placement new usable in constant expressions. At the same time, placement new is a very, maybe even too flexible tool and to use it in a safe way requires casting to void* and then back to T*. This faced some issues, but the acceptance of P2738R1 and the ability of casting from void* in constant expressions made the impossible possible. If you are looking for more details, check P2747R2. P2686R5: constexpr structured bindings and references to constexpr variables This is a rather long (20 pages) proposal and I found it not particularly easy to read. That's not the fault of the authors, the problem is hard to address. The paper which is based on another, went through 5 revisions, discusses various solutions, and lists the wording changes on more than 10 pages. Long story short, you'll be able to declare structured bindings constexpr. As structured bindings behave like references, the same restrictions apply as to constexpr references. Those restrictions become more relaxed. Before, a constexpr reference had to bind to a variable with static storage duration, so that the address doesn't change from one evaluation to another. With C++26, in addition, variables with automatic storage duration are also accepted if and only if the address is constant relative to the stack frame in which the reference or the structured binding lives. In practice, this means that you cannot have a constexpr reference in a lambda to bind to an enclosing function. The reason is that in order to access that variable, the expression is something like this->__x where __x represents the captured address of x. As we don't know at compile time what object this points to, it's not a constant expression. Conclusion In this article, we reviewed how constexpr evolves in the C++26 core language. We are getting constexpr cast from void*, placement new, structured bindings and even exceptions (not discussed today). In the next article, we'll see how the standard library's constexpr support evolves. Connect deeper If you liked this article, please * hit on the like button, * subscribe to my newsletter * and let's connect on Twitter! [yH5BAEAAAA] dev cpp cpp26 structuredbindings constexpr This post is licensed under CC BY 4.0 by the author. [yH5BAEAAAA] [yH5BAEAAAA] Share Recent Update * Raw loops for performance? * The Battle Hardened Developer by Fiodar Sazanavets * C++26: erroneous behaviour * C++26: Removing language features * The big STL Algorithms tutorial: transform Trending Tags cpp books watercooler career tutorial cpp23 stl algorithms self-improvement management Contents Further Reading Feb 26 2025-02-26T00:00:00+01:00 C++26: no more UB in lexing If you ever used C++, for sure you had to face undefined behaviour. Even though it gives extra freedom for implementers, it's dreaded by developers as it may cause havoc in your systems and it's be... Jan 29 2025-01-29T00:00:00+01:00 C++26: attributes in structured bindings We recently talked about C++26's unnamed placeholder and how useful it will be with structured bindings. Before unnamed placeholders, one of our problems was that in structured bindings we could no... Sep 6, 2023 2023-09-06T00:00:00+02:00 C++23: some changes related to templates I know the above title is a bit vague. As we move forward with the introduction of C++23 features, there are going to be some articles like that. At the same time, there are more than two features ... Raw loops for performance? - Comments powered by Disqus. (c) 2025 Sandor Dargo. Some rights reserved. Powered by Jekyll with Chirpy theme. Trending Tags cpp books watercooler career tutorial cpp23 stl algorithms self improvement management