C++ in Embedded Systems - Interview with Author Amar Mahmutbegović
This weeks interview with Amar about his book on C++ on embedded systems:
C++ in Embedded Systems Interview with Author Amar Mahmutbegović
by Jens Weller
Watch the video
September 13-19, Aurora, CO, USA
October 25, Pavia, Italy
November 6-8, Berlin, Germany
November 3-8, Kona, HI, USA
By Meeting C++ | Jul 20, 2025 04:43 AM | Tags: meetingcpp intermediate embedded community c++23 c++20 c++17 basics
This weeks interview with Amar about his book on C++ on embedded systems:
C++ in Embedded Systems Interview with Author Amar Mahmutbegović
by Jens Weller
Watch the video
By Blog Staff | Jul 17, 2025 02:47 PM | Tags: None
In C++, the presence of a user-declared (but not explicitly deleted) copy constructor is enough for the type to be considered copy-constructible by traits like
std::is_copy_constructible
. However, whether that constructor is instantiable is a separate matter—if it attempts to call a deleted base copy constructor, you'll still get a compile-time error when you actually try to use it.
Why does C++ think my class is copy-constructible when it can’t be copy-constructed?
by Raymond Chen
From the article:
Consider the following scenario:
template<typename T>
struct Base
{
// Default-constructible
Base() = default;// Not copy-constructible
Base(Base const &) = delete;
};template<typename T>
struct Derived : Base<T>
{
Derived() = default;
Derived(Derived const& d) : Base<T>(d) {}
};// This assertion passes?
static_assert(
std::is_copy_constructible_v<Derived<int>>);
Why does this assertion pass? It is plainly evident that you cannot copy a Derived<int> because doing so will try to copy the Base<int>, which is not copyable.
By Administrator | Jul 15, 2025 05:32 PM | Tags: None
The 2025-07 mailing of new standards papers is now available.
WG21 Number | Title | Author | Document Date | Mailing Date | Previous Version | Subgroup |
---|---|---|---|---|---|---|
N5012 | WG21 2025-06 Sofia Admin telecon minutes | Nina Ranns | 2025-06-08 | 2025-07 | All of WG21 | |
N5016 | WG21 June 2025 Sofia Hybrid meeting Minutes of Meeting | Nina Ranns | 2025-07-08 | 2025-07 | All of WG21 | |
P0085R2 | Oo... adding a coherent character sequence to begin octal-literals | Axel Naumann | 2025-06-06 | 2025-07 | P0085R1 | EWG Evolution,LEWG Library Evolution |
P0085R3 | Oo... adding a coherent character sequence to begin octal-literals | Axel Naumann | 2025-07-01 | 2025-07 | P0085R2 | EWG Evolution |
P0085R3 | Oo... adding a coherent character sequence to begin octal-literals | Axel Naumann | 2025-07-01 | 2025-07 | P0085R2 | EWG Evolution |
P0085R3 | Oo... adding a coherent character sequence to begin octal-literals | Axel Naumann | 2025-07-01 | 2025-07 | P0085R2 | EWG Evolution |
P0085R3 | Oo... adding a coherent character sequence to begin octal-literals | Axel Naumann | 2025-07-01 | 2025-07 | P0085R2 | EWG Evolution |
P0085R3 | Oo... adding a coherent character sequence to begin octal-literals | Axel Naumann | 2025-07-01 | 2025-07 | P0085R2 | CWG Core |
P0260R18 | C++ Concurrent Queues | Detlef Vollmann | 2025-06-17 | 2025-07 | P0260R17 | LWG Library |
P0260R19 | C++ Concurrent Queues | Detlef Vollmann | 2025-06-18 | 2025-07 | P0260R18 | LWG Library |
P0870R6 | A proposal for a type trait to detect narrowing conversions | Giuseppe D'Angelo | 2025-06-17 | 2025-07 | P0870R5 | SG6 Numerics,LEWG Library Evolution,LWG Library |
P0870R7 | A proposal for a type trait to detect narrowing conversions | Giuseppe D'Angelo | 2025-06-17 | 2025-07 | P0870R6 | SG6 Numerics,LEWG Library Evolution,LWG Library |
P0876R21 | fiber_context - fibers without scheduler | Oliver Kowalke | 2025-07-13 | 2025-07 | P0876R20 | CWG Core,LWG Library |
P1040R8 | std::embed and #depend | JeanHeyd Meneide | 2025-06-22 | 2025-07 | P1040R7 | EWG Evolution |
P1306R5 | Expansion statements | Dan Katz | 2025-06-20 | 2025-07 | P1306R4 | All of WG21 |
P2079R10 | Parallel Scheduler | Lucian Radu Teodorescu | 2025-06-25 | 2025-07 | P2079R9 | LWG Library |
P2079R9 | Parallel Scheduler | Lucian Radu Teodorescu | 2025-06-26 | 2025-07 | P2079R8 | LWG Library |
P2319R5 | Prevent path presentation problems | Victor Zverovich | 2025-06-17 | 2025-07 | P2319R4 | LWG Library |
P2414R8 | Pointer lifetime-end zap proposed solutions | Paul E. McKenney | 2025-06-18 | 2025-07 | P2414R7 | LEWG Library Evolution,LWG Library |
P2414R9 | Pointer lifetime-end zap proposed solutions | Paul E. McKenney | 2025-07-11 | 2025-07 | P2414R8 | EWG Evolution,LEWG Library Evolution |
P2664R11 | Proposal to extend std::simd with permutation API | Daniel Towner | 2025-06-20 | 2025-07 | P2664R10 | LWG Library |
P2781R9 | std::constexpr_wrapper | Zach Laine | 2025-06-17 | 2025-07 | P2781R8 | LWG Library |
P2876R3 | Proposal to extend std::simd with more constructors and accessors | Daniel Towner | 2025-06-17 | 2025-07 | P2876R2 | LWG Library |
P2929R1 | simd_invoke | Daniel Towner | 2025-06-19 | 2025-07 | P2929R0 | LEWG Library Evolution |
P2996R13 | Reflection for C++26 | Barry Revzin | 2025-06-20 | 2025-07 | P2996R12 | CWG Core,LWG Library |
P3008R6 | Atomic floating-point min/max | Gonzalo Brito Gadeschi | 2025-06-19 | 2025-07 | P3008R5 | LWG Library |
P3044R2 | sub-string_view from string | Michael Florian Hava | 2025-06-19 | 2025-07 | P3044R1 | LWG Library |
P3045R6 | Quantities and units library | Mateusz Pusz | 2025-06-19 | 2025-07 | P3045R5 | SG6 Numerics,SG16 Unicode,LEWGI SG18: LEWG Incubator,LEWG Library Evolution |
P3060R3 | Add std::views::indices(n) | Weile Wei | 2025-06-18 | 2025-07 | P3060R2 | LWG Library |
P3091R4 | Better lookups for `map` , `unordered_map`, and `flat_map` | Pablo Halpern | 2025-06-20 | 2025-07 | P3091R3 | LEWG Library Evolution,LWG Library |
P3096R10 | Function Parameter Reflection in Reflection for C++26 | Adam Lach | 2025-06-17 | 2025-07 | P3096R9 | CWG Core,LWG Library |
P3096R11 | Function Parameter Reflection in Reflection for C++26 | Adam Lach | 2025-06-19 | 2025-07 | P3096R10 | EWG Evolution,LEWG Library Evolution,CWG Core,LWG Library |
P3096R12 | Function Parameter Reflection in Reflection for C++26 | Adam Lach | 2025-06-20 | 2025-07 | P3096R11 | CWG Core,LWG Library |
P3100R3 | Implicit contract assertions | Timur Doumler | 2025-07-03 | 2025-07 | P3100R2 | EWG Evolution |
P3104R4 | Bit permutations | Jan Schultke | 2025-06-28 | 2025-07 | P3104R3 | SG6 Numerics,LWG Library |
P3111R7 | Atomic Reduction Operations | Gonzalo Brito Gadeschi | 2025-06-18 | 2025-07 | P3111R6 | CWG Core,LWG Library |
P3111R8 | Atomic Reduction Operations | Gonzalo Brito Gadeschi | 2025-06-19 | 2025-07 | P3111R7 | LWG Library |
P3149R11 | async_scope -- Creating scopes for non-sequential concurrency | Ian Petersen | 2025-06-19 | 2025-07 | P3149R10 | LWG Library |
P3179R9 | C++ parallel range algorithms | Ruslan Arutyunyan | 2025-05-28 | 2025-07 | P3179R8 | LWG Library |
P3211R1 | views::flat_map | Hewill Kang | 2025-07-04 | 2025-07 | P3211R0 | SG9 Ranges,LEWG Library Evolution,LWG Library |
P3216R1 | views::slice | Hewill Kang | 2025-06-28 | 2025-07 | P3216R0 | SG9 Ranges,LEWG Library Evolution,LWG Library |
P3220R1 | views::take_before | Hewill Kang | 2025-06-23 | 2025-07 | P3220R0 | SG9 Ranges,LEWG Library Evolution,LWG Library,Direction Group |
P3223R2 | Making std::istream::ignore less surprising | Jonathan Wakely | 2025-06-20 | 2025-07 | P3223R1 | LWG Library |
P3248R4 | Require [u]intptr_t | Gonzalo Brito Gadeschi | 2025-06-19 | 2025-07 | P3248R3 | LWG Library |
P3290R3 | Integrating Existing Assertions With Contracts | Joshua Berne | 2025-07-11 | 2025-07 | P3290R2 | SG22 Compatibility,LEWG Library Evolution |
P3293R3 | Splicing a base class subobject | Barry Revzin | 2025-06-20 | 2025-07 | P3293R2 | CWG Core,LWG Library |
P3347R3 | Invalid/Prospective Pointer Operations | Paul E. McKenney | 2025-07-11 | 2025-07 | P3347R2 | CWG Core |
P3348R4 | C++26 should refer to C23 not C17 | Jonathan Wakely | 2025-06-19 | 2025-07 | P3348R3 | SG6 Numerics,LWG Library |
P3383R3 | mdspan.at() | Stephan Lachnit | 2025-06-17 | 2025-07 | P3383R2 | LWG Library |
P3394R4 | Annotations for Reflection | Daveed Vandevoorde | 2025-06-20 | 2025-07 | P3394R3 | All of WG21 |
P3411R3 | `any_view` | Hui Xie | 2025-06-18 | 2025-07 | P3411R2 | SG9 Ranges,LEWG Library Evolution |
P3433R1 | Allocator Support for Operation States | Dietmar Kuehl | 2025-06-19 | 2025-07 | P3433R0 | LWG Library |
P3439R3 | Chained comparisons: Safe, correct, efficient | Herb Sutter | 2025-06-19 | 2025-07 | P3439R2 | EWG Evolution |
P3440R1 | Add n_elements named constructor to std::simd | Daniel Towner | 2025-06-13 | 2025-07 | P3440R0 | LEWG Library Evolution |
P3480R6 | std::simd is a range | Matthias Kretz | 2025-06-17 | 2025-07 | P3480R5 | LWG Library |
P3481R4 | std::execution::bulk() issues | Lucian Radu Teodorescu | 2025-06-17 | 2025-07 | P3481R3 | SG1 Concurrency and Parallelism,LEWG Library Evolution,LWG Library |
P3481R5 | std::execution::bulk() issues | Lucian Radu Teodorescu | 2025-06-18 | 2025-07 | P3481R4 | SG1 Concurrency and Parallelism,LEWG Library Evolution,LWG Library |
P3491R3 | define_static_{string,object,array} | Barry Revzin | 2025-06-20 | 2025-07 | P3491R2 | CWG Core,LWG Library |
P3503R3 | Make type-erased allocator use in promise and packaged_task consistent | Nicolas Morales | 2025-06-19 | 2025-07 | P3503R2 | LWG Library |
P3540R2 | #embed Parameter offset | JeanHeyd Meneide | 2025-06-05 | 2025-07 | P3540R1 | CWG Core |
P3552R3 | Add a Coroutine Task Type | Dietmar Kühl | 2025-06-20 | 2025-07 | P3552R2 | All of WG21 |
P3557R3 | High-Quality Sender Diagnostics with Constexpr Exceptions | Eric Niebler | 2025-07-04 | 2025-07 | P3557R2 | LWG Library |
P3560R2 | Error Handling in Reflection | Barry Revzin | 2025-06-20 | 2025-07 | P3560R1 | LWG Library |
P3566R2 | You shall not pass `char*` - Safety concerns working with unbounded null-terminated strings | Marco Foco, Joshua Kriegshauser, Alexey Shevlyakov, Giuseppe D'Angelo | 2025-06-15 | 2025-07 | P3566R1 | LEWGI SG18: LEWG Incubator,SG23 Safety and Security,LEWG Library Evolution |
P3566R2 | You shall not pass `char*` - Safety concerns working with unbounded null-terminated strings | Marco Foco, Joshua Kriegshauser, Alexey Shevlyakov, Giuseppe D'Angelo | 2025-06-15 | 2025-07 | P3566R1 | LEWGI SG18: LEWG Incubator,SG23 Safety and Security,LEWG Library Evolution |
P3570R2 | optional variants in sender/receiver | Fabio Fracassi | 2025-06-18 | 2025-07 | P3570R1 | LWG Library |
P3601R0 | Slides for P3407R1 | Brian Bi | 2025-06-17 | 2025-07 | EWG Evolution | |
P3642R1 | Carry-less product: std::clmul | Jan Schultke | 2025-06-03 | 2025-07 | P3642R0 | SG6 Numerics,LEWGI SG18: LEWG Incubator |
P3642R2 | Carry-less product: std::clmul | Jan Schultke | 2025-07-02 | 2025-07 | P3642R1 | LEWG Library Evolution |
P3647R0 | Slides for P3642R1 | Jan Schultke | 2025-06-18 | 2025-07 | SG6 Numerics,LEWGI SG18: LEWG Incubator | |
P3655R2 | zstring_view | Peter Bindels | 2025-06-15 | 2025-07 | P3655R1 | LEWG Library Evolution |
P3663R2 | Future-proof `submdspan-mapping` | Mark Hoemmen | 2025-07-13 | 2025-07 | P3663R1 | LWG Library |
P3668R2 | Defaulting Postfix Increment and Decrement Operations | Matthew Taylor | 2025-07-13 | 2025-07 | P3668R1 | CWG Core |
P3669R2 | Non-Blocking Support for `std::execution` | Detlef Vollmann | 2025-06-19 | 2025-07 | P3669R1 | SG1 Concurrency and Parallelism,LEWG Library Evolution |
P3687R1 | Final Adjustments to C++26 Reflection | Dan Katz | 2025-06-18 | 2025-07 | P3687R0 | EWG Evolution,LEWG Library Evolution,CWG Core,LWG Library |
P3688R1 | ASCII character utilities | Jan Schultke | 2025-06-28 | 2025-07 | P3688R0 | SG16 Unicode |
P3690R1 | Consistency fix: Make simd reductions SIMD-generic | Olaf Krzikalla | 2025-06-17 | 2025-07 | P3690R0 | LWG Library |
P3691R1 | Reconsider naming of the namespace for "std::simd" | Matthias Kretz | 2025-06-16 | 2025-07 | P3691R0 | LWG Library |
P3692R1 | How to Avoid OOTA Without Really Trying | Paul E. McKenney | 2025-07-10 | 2025-07 | P3692R0 | SG1 Concurrency and Parallelism |
P3697R1 | Minor additions to C++26 standard library hardening | Konstantin Varlamov | 2025-06-20 | 2025-07 | P3697R0 | LEWG Library Evolution,LWG Library |
P3699R1 | Rename `conqueue_errc` | Detlef Vollmann | 2025-06-16 | 2025-07 | P3699R0 | LEWG Library Evolution |
P3705R1 | A Sentinel for Null-Terminated Strings | Eddie Nolan | 2025-06-18 | 2025-07 | P3705R0 | SG9 Ranges,LEWG Library Evolution |
P3705R2 | A Sentinel for Null-Terminated Strings | Eddie Nolan | 2025-06-18 | 2025-07 | P3705R1 | SG9 Ranges,LEWG Library Evolution |
P3709R1 | Reconsider parallel ranges::rotate_copy and ranges::reverse_copy | Ruslan Arutyunyan | 2025-06-02 | 2025-07 | P3709R0 | SG9 Ranges,LEWG Library Evolution |
P3709R2 | Reconsider parallel ranges::rotate_copy and ranges::reverse_copy | Ruslan Arutyunyan | 2025-06-17 | 2025-07 | P3709R1 | SG9 Ranges,LEWG Library Evolution |
P3711R1 | Safer StringViewLike Functions for Replacing char* strings | Marco Foco | 2025-06-19 | 2025-07 | P3711R0 | SG23 Safety and Security,LEWG Library Evolution |
P3713R0 | 2025-05 Library Evolution Poll Outcomes | Inbal Levi | 2025-07-15 | 2025-07 | All of WG21 | |
P3718R0 | Fixing Lazy Sender Algorithm Customization, Again | Eric Niebler | 2025-06-28 | 2025-07 | LEWG Library Evolution,LWG Library | |
P3719R0 | std::is_vector_bool_reference | Yuxuan Chen | 2025-05-20 | 2025-07 | LEWGI SG18: LEWG Incubator,LEWG Library Evolution | |
P3721R0 | Slides for P3639R0 | Jan Schultke | 2025-06-03 | 2025-07 | SG22 Compatibility | |
P3722R0 | Slides for P3568R1 | Jan Schultke | 2025-05-27 | 2025-07 | SG22 Compatibility | |
P3724R0 | Integer division | Jan Schultke | 2025-06-05 | 2025-07 | SG6 Numerics,LEWG Library Evolution | |
P3725R0 | Filter View Extensions for Input Ranges | Nicolai Josuttis | 2025-06-19 | 2025-07 | SG9 Ranges,LEWG Library Evolution,LWG Library | |
P3725R1 | Filter View Extensions for Input Ranges | Nicolai Josuttis | 2025-06-23 | 2025-07 | P3725R0 | SG9 Ranges,LEWG Library Evolution,LWG Library |
P3726R0 | Adjustments to Union Lifetime Rules | Barry Revzin | 2025-07-13 | 2025-07 | EWG Evolution,CWG Core | |
P3727R0 | Update Annex E based on Unicode 15.1 UAX #31 | Steve Downey | 2025-06-11 | 2025-07 | SG16 Unicode,CWG Core | |
P3729R0 | Aligning span and string_view | Michael Florian Hava | 2025-06-23 | 2025-07 | LEWG Library Evolution | |
P3730R0 | Slides for P3104R3 | Jan Schultke | 2025-06-04 | 2025-07 | LEWG Library Evolution | |
P3731R0 | #embed Preprocessor Parameter Order | JeanHeyd Meneide | 2025-06-05 | 2025-07 | SG22 Compatibility,EWG Evolution | |
P3732R0 | Numeric Range Algorithms | Ruslan Arutyunyan | 2025-06-27 | 2025-07 | SG1 Concurrency and Parallelism,SG9 Ranges | |
P3733R0 | More named universal character escapes | Jan Schultke | 2025-06-28 | 2025-07 | SG16 Unicode | |
P3734R0 | Not all predicates must be regular | Jan Schultke | 2025-06-14 | 2025-07 | SG9 Ranges | |
P3735R0 | partial_sort_n, nth_element_n | Jan Schultke | 2025-06-28 | 2025-07 | SG9 Ranges | |
P3736R0 | Slides against P2971R3 - No implication for C++ | Jan Schultke | 2025-06-27 | 2025-07 | EWG Evolution | |
P3737R0 | std::array is a wrapper for an array! | Jan Schultke | 2025-06-11 | 2025-07 | LEWG Library Evolution | |
P3738R0 | Make std::make_from_tuple SFINAE friendly | Yihan Wang | 2025-06-10 | 2025-07 | LEWG Library Evolution | |
P3739R0 | Standard Library Hardening - using std::optional | Jarrad J Waterloo | 2025-06-10 | 2025-07 | LWG Library | |
P3739R1 | Standard Library Hardening - using std::optional | Jarrad J Waterloo | 2025-06-10 | 2025-07 | P3739R0 | LWG Library |
P3740R0 | Last chance to fix std::nontype | Jan Schultke | 2025-06-14 | 2025-07 | LEWG Library Evolution | |
P3740R1 | Last chance to fix std::nontype | Jan Schultke | 2025-06-19 | 2025-07 | P3740R0 | LEWG Library Evolution |
P3741R0 | views::set_operations | Hewill Kang | 2025-06-21 | 2025-07 | SG9 Ranges | |
P3742R0 | C++ Standard Library Ready Issues to be moved in Sofia, Jun. 2025 | Jonathan Wakely | 2025-06-13 | 2025-07 | All of WG21 | |
P3745R0 | Rebuttal to P1144R13 | Pablo Halpern | 2025-07-02 | 2025-07 | EWG Evolution,LEWG Library Evolution | |
P3746R0 | LEWG Slides for P3637R0 Inherit std::meta::exception from std::exception | Nevin Liber | 2025-06-16 | 2025-07 | LEWG Library Evolution | |
P3747R0 | Call side return type deduction | Thomas Mejstrik | 2025-06-17 | 2025-07 | EWGI SG17: EWG Incubator | |
P3748R0 | Inspecting exception_ptr works should be constexpr. | Hana Dusíková | 2025-06-18 | 2025-07 | LEWG Library Evolution | |
P3749R0 | Slides in response to P3655R2 - Concerns regarding std::zstring_view | Jan Schultke | 2025-06-27 | 2025-07 | LEWG Library Evolution | |
P3752R0 | Core Language Working Group "ready" Issues for the June, 2025 meeting | Jens Maurer | 2025-06-20 | 2025-07 | CWG Core | |
P3753R0 | Slides for P3740R0 - Last chance to fix std::nontype | Jan Schultke | 2025-06-20 | 2025-07 | LEWG Library Evolution | |
P3753R1 | Slides for P3740R1 - Last chance to fix std::nontype | Jan Schultke | 2025-06-20 | 2025-07 | P3753R0 | LEWG Library Evolution |
P3754R0 | Slides for P3100R2 presentation to EWG | Timur Doumler | 2025-06-20 | 2025-07 | EWG Evolution | |
P3757R0 | Remove value-type invocability requirement from indirect unary callable concepts | Hewill Kang | 2025-06-21 | 2025-07 | SG9 Ranges,LEWG Library Evolution,LWG Library | |
P3760R0 | Presentation: constexpr 'Parallel' Algorithms | Oliver Rosten | 2025-06-21 | 2025-07 | LEWG Library Evolution | |
P3763R0 | Remove redundant reserve_hint members from view classes | Hewill Kang | 2025-06-21 | 2025-07 | SG9 Ranges,LEWG Library Evolution,LWG Library | |
P3764R0 | A utility function for propagating the most significant bit | Jan Schultke | 2025-07-15 | 2025-07 | SG6 Numerics | |
P3765R0 | Deprecate implicit conversion from bool to character types | Jan Schultke | 2025-07-12 | 2025-07 | EWG Evolution | |
P3769R0 | Clarification of placement new deallocation | Lauri Vasama | 2025-06-22 | 2025-07 | EWG Evolution,CWG Core | |
P3771R0 | constexpr mutex, locks, and condition variable | Hana Dusíková | 2025-06-30 | 2025-07 | SG1 Concurrency and Parallelism,EWG Evolution,LEWG Library Evolution | |
P3772R0 | std::simd overloads for bit permutations | Jan Schultke | 2025-06-28 | 2025-07 | SG6 Numerics | |
P3774R0 | Rename std::nontype, and make it broadly useful | Jan Schultke | 2025-07-15 | 2025-07 | LEWG Library Evolution | |
P3778R0 | Fixing `type_order` template definition | Gašper Ažman | 2025-07-03 | 2025-07 | LEWG Library Evolution,LWG Library | |
P3780R0 | Detecting bitwise trivially relocatable types | Giuseppe D'Angelo | 2025-07-10 | 2025-07 | EWG Evolution,LEWG Library Evolution | |
P3781R0 | is_*_type should imply is_type | Xavier Bonaventura | 2025-07-05 | 2025-07 | SG20 Education,EWG Evolution | |
P3784R0 | range-if | Michael Florian Hava | 2025-07-10 | 2025-07 | EWGI SG17: EWG Incubator | |
P3785R0 | Library Wording Changes for Defaulted Postfix Increment and Decrement Operators | Matthew Taylor | 2025-07-13 | 2025-07 | LWG Library | |
P3787R0 | Adjoints to "Enabling list-initialization for algorithms": uninitialized_fill | Giuseppe D'Angelo | 2025-07-10 | 2025-07 | LEWG Library Evolution,LWG Library | |
P3788R0 | Fixing `std::complex` binary operators | Mateusz Pusz | 2025-07-11 | 2025-07 | SG6 Numerics,LEWG Library Evolution | |
P3790R0 | Pointer lifetime-end zap proposed solutions: Bag-of-bits pointer class | Paul E. McKenney | 2025-07-13 | 2025-07 | LEWG Library Evolution | |
P3791R0 | constexpr deterministic random | Hana Dusíková | 2025-07-15 | 2025-07 | LEWG Library Evolution | |
P3792R0 | Why `constant_wrapper` is not a usable replacement for `nontype` | Bronek Kozicki | 2025-07-13 | 2025-07 | LEWG Library Evolution,LWG Library | |
P3793R0 | Better shifting | Brian Bi | 2025-07-15 | 2025-07 | SG6 Numerics | |
P3794R0 | An idea or two on renaming the nontype tag | Zhihao Yuan | 2025-07-13 | 2025-07 | LEWG Library Evolution | |
P3795R0 | Miscellaneous Reflection Cleanup | Barry Revzin | 2025-07-15 | 2025-07 | EWG Evolution | |
P3796R0 | Coroutine Task Issues | Dietmar Kühl | 2025-07-15 | 2025-07 | SG1 Concurrency and Parallelism,LEWG Library Evolution,LWG Library | |
P3798R0 | The unexpected in std::expected | Alex Kremer | 2025-07-14 | 2025-07 | LEWGI SG18: LEWG Incubator,LEWG Library Evolution,LWG Library | |
P3799R0 | 2025-07 Library Evolution Polls | Inbal Levi | 2025-07-15 | 2025-07 | LEWG Library Evolution | |
P3801R0 | Concerns about the design of std::execution::task | Jonathan Müller | 2025-07-15 | 2025-07 | LEWG Library Evolution | |
P3802R0 | Poor Functions | Daveed Vandevoorde | 2025-07-15 | 2025-07 | EWG Evolution,LEWG Library Evolution |
By Blog Staff | Jul 15, 2025 02:43 PM | Tags: None
While C++ doesn’t have native syntax for returning multiple values like some other languages, modern C++ offers powerful tools to accomplish the same goal. With features like
std::tuple
, structured bindings, std::expected
, and std::optional
, handling multiple return values—and even error codes—has become both clean and expressive.
Returning several values from a function in C++ (C++23 edition)
by Daniel Lemire
From the article:
Many programming languages such as the Go programming language are designed to make it easy to return several values at once from a function. In Go, it is often used to return an optional error code. The C++ programming language does not have a built-in support for returning several values. However, several standard types can serve the same purpose. If you need to return two values, you can use an std::pair instance. If you need to return two or more values, an std::tuple instance will do. With recent C++ standards, it works really well!
Suppose we want to compute a division with a string error message when one is trying to divided by zero:
std::tuple<int,std::string> divide(int a, int b) { if (b == 0) { return {0, "Error: Division by zero"}; } return {a / b, "Success"}; }This approach works nicely. The code is clear and readable.
You might be concerned that we are fixing the type (int). If you want to write one function for all integer types, you can do so with concepts, like so:
By Blog Staff | Jul 11, 2025 02:37 PM | Tags: None
Starting from C++23, standard containers support a new set of constructor overloads. These constructors take a
std::from_range
tag, a range and an optional allocator. These from_range
constructors make it easier to construct containers from ranges, helping make C++ code more concise, more expressive, and less error-prone.
Constructing Containers from Ranges in C++23
by Sandor Dargo
From the article:
I’ve written plenty on this blog about standard algorithms, but far less about ranges. That’s mostly because, although I’ve had production-ready compilers with C++20 ranges since late 2021, the original ranges library lacked a few key capabilities.
The biggest gap was at the end of a pipeline: you could transform data lazily, but you couldn’t drop the result straight into a brand-new container. What you got back was a view; turning that view into, say, a
std::vector
still required the old iterator-pair constructor.C++23 fixes that in two complementary ways:
std::to
(an adaptor that finishes a pipeline by converting to a container), andfrom_range
constructors on every standard container.Today we’ll focus on the second improvement, because it’s the one you can implement in your own types, too.
The
from_range
constructorEvery standard container now supports a new set of constructors that make integration with ranges smoother — the so-called
from_range
constructors.These constructors allow you to build a container directly from a range, rather than from a pair of iterators.
By Blog Staff | Jul 9, 2025 02:34 PM | Tags: None
Time flies—C++ Insights just turned 7! To celebrate, I’ve upgraded the tool to Clang 20, unlocking even more C++23 and C++26 features for you to explore.
C++ Insights now uses Clang 20
by Andreas Fertig
From the article:
size_t
For a long time now, when you used
size_t
orstd::size_t
the resulting transformation kept the name. It did not expand to the underlying machine-specific date type. To be honest, that was more like a happy accident. Clang 20 came with two changes to libc++The first https://github.com/llvm/llvm-project/commit/d6832a611a7c4ec36f08b1cfe9af850dad32da2e modularized
<cstddef>
for better internal structuring, avoiding too much content to be included. This patch was followed by a second one: https://github.com/llvm/llvm-project/commit/5acc4a3dc0e2145d2bfef47f1543bb291c2b866a. This one now made an interesting change.Previously, libc++ defined
std::size_t
as
1using ::size_t _LIBCPP_USING_IF_EXISTS;
As the second patch highlighted, this required including the operating systems
<stddef.h>
. In the spirit of reducing unnecessary includes the line was changed to:
1using size_t = decltype(sizeof(int));
This is an easy C++ solution to get the proper data type for
size_t
. Which is great. Yet, the AST nodes of the two versions look different. Previously, the operating system (macOS in this case) defined in its header:
1typedef unsigned long size_t;
Well, with the new version, the transformation no longer stops at
size_t
but expands it all down tounsigned long
. This probably should have been the case from the beginning, but I liked that tests and transformations did not change across platforms in this specific case. However, there are other instances where the transformation did yield different output on different platforms, so I accept this one.
By Blog Staff | Jul 7, 2025 02:31 PM | Tags: None
Visual Studio 2022 version 17.14 is now generally available! This post summarizes the new features you can find in this release for C++. You can download Visual Studio 2022 from the Visual Studio downloads page or upgrade your existing installation by following the Update Visual Studio Learn page.
What’s New for C++ Developers in Visual Studio 2022 17.14
by Sy Brand
From the article:
We’ve made a myriad of fixes and improvements to the MSVC compiler and standard library. See C++ Language Updates in MSVC in Visual Studio 2022 17.14 for a full list of changes on the compiler side, and the STL Changelog for all the standard library updates.
Compiler
We’ve added support for several C++23 features, which are available under the
/std:c++latest
and/std:c++23preview
flags.You can now omit
auto lambda = [] constexpr { }; //no '()' needed after the capture list()
in some forms of lambdas that previously required them, thanks to P1102R2:
We implemented if consteval
, with which you can run different code depending on whether the statement is executed at compile time or run time. This is useful for cases where your run time version can be heavily optimized with compiler intrinsics or inline assembly that are not available at compile time:
constexpr size_t strlen(char const* s) {
if consteval {
// if executed at compile time, use a constexpr-friendly algorithm
for (const char *p = s; ; ++p) {
if (*p == '\0') {
return static_cast<std::size_t>(p - s);
}
}
} else {
// if executed at run time, use inline assembly
__asm__("SSE 4.2 magic");
}
}
By Blog Staff | Jul 3, 2025 02:29 PM | Tags: None
C++’s undefined behaviour impacts safety. Sandor Dargo explains how and why uninitialised reads will become erroneous behaviour in C++26, rather than being undefined behaviour.
C++26: Erroneous Behaviour
by Sandor Dargo
From the article:
If you pick a random talk at a C++ conference these days, there is a fair chance that the speaker will mention safety at least a couple of times. It’s probably fine like that. The committee and the community must think about improving both the safety situation and the reputation of C++.
If you follow what’s going on in this space, you are probably aware that people have different perspectives on safety. I think almost everybody finds it important, but they would solve the problem in their own way.
A big source of issues is certain manifestations of undefined behaviour. It affects both the safety and the stability of software. I remember that a few years ago when I was working on some services which had to support a 10× growth, one of the important points was to eliminate undefined behaviour as much as possible. One main point for us was to remove uninitialized variables which often lead to crashing services.
Thanks to P2795R5 by Thomas Köppe, uninitialized reads won’t be undefined behaviour anymore – starting from C++26. Instead, they will get a new behaviour called ‘erroneous behaviour’.
The great advantage of erroneous behaviour is that it will work just by recompiling existing code. It will diagnose where you forgot to initialize variables. You don’t have to systematically go through your code and let’s say declare everything as auto to make sure that every variable has an initialized value. Which you probably wouldn’t do anyway.
By Blog Staff | Jul 1, 2025 02:26 PM | Tags: None
Senders/receivers can be used to introduce concurrency. Lucian Radu Teodorescu describes how to implement senders.
Writing Senders
by Lucian Radu Teodorescu
From the article:
If people are just using frameworks based on
std::execution
, they mainly need to care about senders and schedulers. These are user-facing concepts. However, if people want to implement sender-ready abstractions, they also need to consider receivers and operation states – these are implementer-side concepts. As this article mainly focuses on the implementation of sender abstractions, we need to discuss these two concepts in more detail.A receiver is defined in P2300 as “a callback that supports more than one channel” [P2300R10]. The proposal defines a concept for a receiver, unsurprisingly called
receiver
. To model this concept, a type needs to meet the following conditions:
- It must be movable and copyable.
- It must have an inner type alias named
receiver_concept
that is equal toreceiver_t
(or a derived type).std::execution::get_env()
must be callable on an object of this type (to retrieve the environment of the receiver).A receiver is the object that receives the sender’s completion signal, i.e., one of
set_value()
,set_error()
, orset_stopped()
. As explained in the December 2024 issue [Teodorescu24], a sender may have different value completion types and different error completion types. For example, the same sender might sometimes complete withset_value(int, int)
, sometimes withset_value(double)
, sometimes withset_error(std::exception_ptr)
, sometimes withset_error(std::error_code)
, and sometimes withset_stopped()
. This implies that a receiver must also be able to accept multiple types of completion signals.
By Blog Staff | Jun 27, 2025 02:07 PM | Tags: None
In recent weeks, we’ve explored language features and library features becoming constexpr
in C++26. Those articles weren’t exhaustive — I deliberately left out one major topic: exceptions.
Starting with C++26, it will become possible to throw exceptions during constant evaluation. This capability is enabled through both language and library changes. Given the significance of this feature, it deserves its own dedicated post.
C++26: constexpr Exceptions
by Sandor Dargo
From the article:
P3068R6: Allowing exception throwing in constant-evaluation
The proposal for static reflection suggested allowing exceptions in constant-evaluated code, and P3068R6 brings that feature to life.
constexpr
exceptions are conceptually similar toconstexpr
allocations. Just as aconstexpr string
can’t escape constant evaluation and reach runtime,constexpr
exceptions also have to remain within compile-time code.Previously, using
throw
in aconstexpr
context caused a compilation error. With C++26, such code can now compile — unless an exception is actually thrown and left uncaught, in which case a compile-time error is still issued. But the error now provides more meaningful diagnostics.