January 2025

Senders/Receivers: An Introduction -- Lucian Radu Teodorescu

Depositphotos_498706732_S.jpgC++26 will introduce a new concurrency feature called std::execution, or senders/receivers. Lucian Radu Teodorescu explains the idea and how to use these in detail.

Senders/Receivers: An Introduction

by Lucian Radu Teodorescu

From the article:

In June 2024, at the WG21 plenary held in St. Louis, the P2300R10: std::execution paper [P2300R10], also known as senders/receivers, was formally adopted for inclusion in C++ 26. The content of the paper quickly found its way into the working draft for the C++ standard [WG21]. You can find more about the highlights of the St. Louis meeting in Herb Sutter’s trip report [Sutter24].

Senders/receivers represent one of the major additions to C++, as they provide an underlying model for expressing computations, adding support for concurrency, parallelism, and asynchrony. By using senders/receivers, one can write programs that heavily and efficiently exploit concurrency, all while maintaining thread safety (no deadlocks, race conditions, etc.). This is applicable not only to a few classes of concurrent problems but, at least in theory, to all types of concurrency problems. Senders/receivers provide a cost-free way of expressing computations that can run on different hardware with different constraints. They support creating computation chains that execute work on the CPU, GPU, and also enable non-blocking I/O.

Although the proposal has many advantages, there are still people who see the addition of this feature to the C++ standard at this point as a mistake. Some of the cited reasons are the complexity of the feature, compilation times, immaturity, and teachability. The last one caught my attention.

In this article, I plan to provide an introduction to senders/receivers as described in P2300 (and some related papers). The goal is not necessarily to showcase the many advantages of this model or delve into the details of complex topics. Rather, it is to offer a gentle introduction for those who have never read the paper or watched a talk on senders/receivers. We want the reader to understand the basic concepts of using senders/receivers without needing to grasp the intricate details of their implementation.

The hope is that, by the end of the article, the reader will be able to write some programs that use senders/receivers. The examples here are written as if the reader is coding with the feature already included in the standard library. Currently, no standard library provider ships senders/receivers; however, the reader can use the reference implementation of the feature [stdexec].

CopperSpice: C++20 and Two's Complement

New video on the CopperSpice YouTube Channel:

C++20 and Two's Complement

by Barbara Geller and Ansel Sermersheim

About the video:

Someone mentioned C++20 is unusable because the standard now requires 2' Complement. Is is possible that he has a point and if so, on what basis did he make this claim?

We encourage everyone to watch our video to discover the history of Binary Representation.

Take a look and remember to subscribe.

Static Reflection in C++ -- Wu Yongwei

Depositphotos_226578348_S.jpgStatic reflection is under consideration for C++26. Wu Yongwei demonstrates how to achieve reflection now and shows some examples of what C++26 might make possible.

Static reflection will be an important part of C++ compile-time programming, as I discussed in the October issue of Overload [Wu24]. This time I will discuss static reflection in detail, including how to emulate it right now, before it’s been added to the standard.

Static Reflection in C++

by Wu Yongwei

From the article:

Background

Many programming languages support reflection (Python and Java, for example). C++ is lagging behind.

While this is the case, things are probably going to change in C++26. Also, what will be available in C++ will be very different from what is available in languages like Java or Python. The keyword is ‘static’.

Andrew Sutton defined ‘static reflection’ as follows [Sutton21]:

Static reflection is the integral ability for a metaprogram to observe its own code and, to a limited extent, generate new code at compile time.

‘Compile-time’ is the special sauce in C++, and it allows us to do things impossible in other languages:

  • Zero-overhead abstraction. As Bjarne Stroustrup famously put it, ‘What you don’t use, you don’t pay for. What you do use, you couldn’t hand-code any better.’ If you do not need static reflection, it will not make your program fatter or slower. But it will be at your hand when you do need it.
  • High performance. Due to the nature of compile-time reflection, it is possible to achieve unparalleled performance, when compared with languages like Java or Python.
  • Versatility at both compile time and run time. The information available at compile time can be used at run time, but not vice versa. C++ static reflection can do things that are possible in languages like Java, but there are things that C++ can do but are simply impossible in other languages.

What we want from reflection

When we talk about static reflection, what do we really want? We really want to see what a compiler can see, and we want to be able to use the relevant information in the code. The most prominent cases are enum and struct. We want to be able to iterate over all the enumerators, and know their names and values. We want to be able to iterate over all the data members of a struct, and know their names and types. Obviously, when a data member is an aggregate, we also want to be able to recurse into it during reflection. And so on.

Regretfully, we cannot do all these things today with ‘standard’ definitions. Yes, in some implementations it is possible to hack out some of the information with various tricks. I would prefer to use macros and template techniques to achieve the same purpose, as the code is somewhat neater, more portable, and more maintainable – at the cost of using non-standard definition syntaxes. Of course, nothing beats direct support from the future C++ standard.

C++ programmer's guide to undefined behavior: part 12 of 11

Your attention is invited to the final part of an e-book on undefined behavior. This is not a textbook, as it's intended for those who are already familiar with C++ programming. It's a kind of C++ programmer's guide to undefined behavior and to its most secret and exotic corners. The book was written by Dmitry Sviridkin and edited by Andrey Karpov. Why is it the chapter 12 of 11? We couldn't resist highlighting the favorite error of C and C++ programmers that even has its own name—the Off-by-one Error.

C++ programmer's guide to undefined behavior: part 12 of 11

by Dmitry Sviridkin

From the article:

LLVM can generate the ud2 instruction on x86, which is an invalid instruction, often used as an indicator of unreachable code. If the program tries to execute it, it'll crash with the SIGILL signal. The code that causes undefined behavior can be marked as unreachable and replaced with ud2 or discarded in the future. In our wonderful example, the compiler is fully aware that buffer.size() == 0, and it hasn't been changed.

 

Learning to read C++ Compiler Errors: Failing to Create a shared_ptr -- Raymond Chen

Depositphotos_478507824_S.jpgThe trick to understanding C++ compiler error messages is to focus on two things. First, look at the beginning of the error message, which tells you what went wrong at a very low level. Then skip over the intermediate errors that follow the chain of calls until you end up at the line of code that you wrote. That original line of code is the one that is leading the compiler to a bad place. After that, you sometimes get supplemental information that helps you understand the low-level error better.

Learning to read C++ Compiler Errors: Failing to Create a shared_ptr

by Raymond Chen

From the article:

Consider the following erroneous code:

#include <memory>
#include <string>

struct WidgetOptions
{
    // imagine there is interesting stuff here
};

struct Widget
{
    Widget(WidgetOptions const* options);

    // imagine there is other interesting stuff here
};

void oops()
{
    WidgetOptions options;

    // The next line fails to compile
    std::shared_ptr<Widget> widget =
        std::make_shared<Widget>(options);
}

Here comes the error explosion.

// gcc
In file included from bits/stl_tempbuf.h:61,
                 from memory:66,
                 from sample.cpp:1:
bits/stl_construct.h: In instantiation of 'void std::_Construct(_Tp*, _Args&& ...) [with _Tp = Widget; _Args = {WidgetOptions&}]':
bits/alloc_traits.h:657:19:   required from 'static void std::allocator_traits<std::allocator<void> >::construct(allocator_type&, _Up*, _Args&& ...) [with _Up = Widget; _Args = {WidgetOptions&}; allocator_type = std::allocator<void>]'
  657 |         { std::_Construct(__p, std::forward<_Args>(__args)...); }
      |           ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bits/shared_ptr_base.h:607:39:   required from 'std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {WidgetOptions&}; _Tp = Widget; _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
  607 |           allocator_traits<_Alloc>::construct(__a, _M_ptr(),
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
  608 |               std::forward<_Args>(__args)...); // might throw
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
bits/shared_ptr_base.h:969:16:   required from 'std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = Widget; _Alloc = std::allocator<void>; _Args = {WidgetOptions&}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
  969 |           auto __pi = ::new (__mem)
      |                       ^~~~~~~~~~~~~
  970 |             _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bits/shared_ptr_base.h:1713:14:   required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<void>; _Args = {WidgetOptions&}; _Tp = Widget; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
 1713 |         : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bits/shared_ptr.h:463:59:   required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<void>; _Args = {WidgetOptions&}; _Tp = Widget]'
  463 |         : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
      |                                                                  ^
bits/shared_ptr.h:1007:14:   required from 'std::shared_ptr<typename std::enable_if<(! std::is_array<_Tp>::value), _Tp>::type> std::make_shared(_Args&& ...) [with _Tp = Widget; _Args = {WidgetOptions&}; typename enable_if<(! is_array<_Tp>::value), _Tp>::type = Widget]'
 1007 |       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1008 |                              std::forward<_Args>(__args)...);
      |                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sample.cpp:22:33:   required from here
   22 |         std::make_shared<Widget>(options);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
bits/stl_construct.h:119:7: error: no matching function for call to 'Widget::Widget(WidgetOptions&)'
  119 |       ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sample.cpp:11:5: note: candidate: 'Widget::Widget(const WidgetOptions*)'
   11 |     Widget(WidgetOptions const* options);
      |     ^~~~~~
sample.cpp:11:33: note:   no known conversion for argument 1 from 'WidgetOptions' to 'const WidgetOptions*'
   11 |     Widget(WidgetOptions const* options);
      |            ~~~~~~~~~~~~~~~~~~~~~^~~~~~~
sample.cpp:9:8: note: candidate: 'constexpr Widget::Widget(const Widget&)'
    9 | struct Widget
      |        ^~~~~~
sample.cpp:9:8: note:   no known conversion for argument 1 from 'WidgetOptions' to 'const Widget&'
sample.cpp:9:8: note: candidate: 'constexpr Widget::Widget(Widget&&)'
sample.cpp:9:8: note:   no known conversion for argument 1 from 'WidgetOptions' to 'Widget&&'
Compiler returned: 1
 

Replace CRTP with Concepts -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGThis article explores how C++20 concepts can replace CRTP when implementing static interfaces for a family of classes. By leveraging concepts, we achieve cleaner, more readable, and less error-prone code—provided you have access to C++20.

Replace CRTP with Concepts

by Sandor Dargo

From the article:

In my Meeting C++ 2024 trip report, among my favourite ideas I mentioned Klaus Iglberger’s talk where he mentioned the possibility of replacing the curiously returning template pattern with the help of class tagging and concepts.

Class tagging might mean different things in different contexts, or at least might be implemented in different ways. The end goal is to mark, in other words, tag classes or functions to be used in certain contexts, with certain algorithms. As you’ll see, in our case it’ll also be a tool to prevent duck typing.

We are going to see an example implementation of a static interface with CRTP with a couple of different derived classes, then we’ll see the implementation without CRTP.

The CRTP solution

With the static interface, we are creating a static family of types. There is no need for dynamic polymorphism to share the same interface. It’s still granted through a base class, which is a template taking the deriving class as a parameter.

 

 

2025-01 Mailing Available

The 2025-01 mailing of new standards papers is now available.

 

WG21 Number Title Author Document Date Mailing Date Previous Version Subgroup
P0149R1 Generalised member pointers Jeff Snyder 2025-01-13 2025-01 P0149R0 EWG Evolution
P0260R14 C++ Concurrent Queues Detlef Vollmann 2025-01-12 2025-01 P0260R13 SG1 Concurrency and Parallelism,LEWG Library Evolution
P0876R19 fiber_context - fibers without scheduler Oliver Kowalke 2025-01-13 2025-01 P0876R18 EWG Evolution,CWG Core,LWG Library
P1030R8 std::filesystem::path_view Niall Douglas 2024-12-21 2025-01 P1030R7 LEWG Library Evolution
P1839R7 Accessing object representations Brian Bi 2025-01-11 2025-01 P1839R6 CWG Core
P2079R6 System execution context Lucian Radu Teodorescu 2025-01-13 2025-01 P2079R5 SG1 Concurrency and Parallelism,LEWG Library Evolution
P2414R5 Pointer lifetime-end zap proposed solutions Paul E. McKenney 2025-01-11 2025-01 P2414R4 SG1 Concurrency and Parallelism,LEWG Library Evolution,LWG Library
P2434R3 Nondeterministic pointer provenance S. Davis Herring 2025-01-13 2025-01 P2434R2 SG22 Compatibility,EWG Evolution,CWG Core
P2654R1 Modules and Macros Alisdair Meredith 2025-01-13 2025-01 P2654R0 EWG Evolution,LEWG Library Evolution
P2663R6 Proposal to support interleaved complex values in std::simd Daniel Towner 2025-01-13 2025-01 P2663R5 LEWG Library Evolution
P2664R9 Proposal to extend std::simd with permutation API Daniel Towner 2025-01-13 2025-01 P2664R8 SG1 Concurrency and Parallelism,LEWG Library Evolution
P2688R5 Pattern Matching: `match` Expression Michael Park 2025-01-13 2025-01 P2688R4 EWG Evolution
P2719R2 Type-aware allocation and deallocation functions Louis Dionne 2025-01-06 2025-01 P2719R1 EWG Evolution,CWG Core
P2719R3 Type-aware allocation and deallocation functions Louis Dionne 2025-01-08 2025-01 P2719R2 EWG Evolution,CWG Core
P2746R7 Deprecate and Replace Fenv Rounding Modes Hans Boehm 2025-01-12 2025-01 P2746R6 SG6 Numerics,LEWG Library Evolution
P2758R4 Emitting messages at compile time Barry Revzin 2025-01-07 2025-01 P2758R3 LEWG Library Evolution,CWG Core
P2806R3 do expressions Barry Revzin 2025-01-12 2025-01 P2806R2 EWG Evolution
P2825R4 Overload resolution hook: declcall( unevaluated-call-expression ) Gašper Ažman 2025-01-13 2025-01 P2825R3 EWG Evolution,CWG Core
P2830R8 Standardized Constexpr Type Ordering Gašper Ažman 2025-01-09 2025-01 P2830R7 LWG Library
P2830R9 Standardized Constexpr Type Ordering Gašper Ažman 2025-01-10 2025-01 P2830R8 EWG Evolution,LEWG Library Evolution,CWG Core,LWG Library
P2841R6 Concept and variable-template template-parameters Corentin Jabot 2025-01-13 2025-01 P2841R5 CWG Core
P2843R1 Preprocessing is never undefined Alisdair Meredith 2025-01-13 2025-01 P2843R0 SG22 Compatibility,EWG Evolution
P2883R1 `offsetof` Should Be A Keyword In C++26 Alisdair Meredith 2025-01-10 2025-01 P2883R0 EWGI SG17: EWG Incubator,EWG Evolution
P2899R0 Contracts for C++ - Rationale Timur Doumler 2025-01-13 2025-01   SG21 Contracts,EWG Evolution,LEWG Library Evolution
P2900R13 Contracts for C++ Joshua Berne 2025-01-13 2025-01 P2900R12 CWG Core,LWG Library
P2933R3 std::simd overloads for <bit> header Daniel Towner 2025-01-13 2025-01 P2933R2 LWG Library
P2952R2 auto& operator=(X&&) = default Arthur O'Dwyer 2025-01-08 2025-01 P2952R1 CWG Core
P2953R1 Forbid defaulting operator=(X&&) && Arthur O'Dwyer 2025-01-08 2025-01 P2953R0 EWGI SG17: EWG Incubator
P2971R3 Implication for C++ Walter E Brown 2025-01-12 2025-01 P2971R2 EWG Evolution,LEWG Library Evolution
P2988R9 std::optional<T&> Steve Downey 2025-01-13 2025-01 P2988R8 LEWG Library Evolution,LWG Library
P2996R9 Reflection for C++26 Barry Revzin 2025-01-13 2025-01 P2996R8 EWG Evolution
P3019R12 Vocabulary Types for Composite Class Design Jonathan Coe 2025-01-12 2025-01 P3019R11 LEWG Library Evolution,LWG Library
P3045R5 Quantities and units library Mateusz Pusz 2025-01-13 2025-01 P3045R4 SG6 Numerics,SG16 Unicode,LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3070R2 Formatting enums Victor Zverovich 2025-01-13 2025-01 P3070R1 LEWG Library Evolution
P3081R1 Core safety profiles for C++26 Herb Sutter 2025-01-06 2025-01 P3081R0 EWG Evolution,LEWG Library Evolution
P3086R3 Proxy: A Pointer-Semantics-Based Polymorphism Library Mingxin Wang 2025-01-13 2025-01 P3086R2 LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3094R6 std::basic_fixed_string Mateusz Pusz 2025-01-10 2025-01 P3094R5 LEWG Library Evolution
P3111R3 Atomic Reduction Operations Gonzalo Brito Gadeschi 2025-01-13 2025-01 P3111R2 EWG Evolution,LEWG Library Evolution
P3125R3 constexpr pointer tagging Hana Dusíková 2025-01-13 2025-01 P3125R2 LEWG Library Evolution
P3139R1 Pointer cast for unique_ptr Zhihao Yuan 2024-12-27 2025-01 P3139R0 LEWG Library Evolution
P3148R1 Formatting of chrono Time Values Alan Talbot 2025-01-13 2025-01 P3148R0 LEWG Library Evolution
P3164R3 Early Diagnostics for Sender Expressions Eric Niebler 2025-01-09 2025-01 P3164R2 LEWG Library Evolution
P3176R1 The Oxford variadic comma Jan Schultke 2024-12-18 2025-01 P3176R0 CWG Core
P3179R5 C++ parallel range algorithms Ruslan Arutyunyan 2025-01-13 2025-01 P3179R4 LEWG Library Evolution
P3206R0 A sender query for completion behaviour Maikel Nadolski 2025-01-13 2025-01   SG1 Concurrency and Parallelism
P3229R0 Making erroneous behaviour compatible with Contracts Timur Doumler 2025-01-13 2025-01   SG21 Contracts,EWG Evolution,LEWG Library Evolution
P3289R1 Consteval blocks Daveed Vandevoorde 2025-01-12 2025-01 P3289R0 EWG Evolution,CWG Core
P3347R1 Invalid/Prospective Pointer Operations Paul E. McKenney 2025-01-11 2025-01 P3347R0 EWG Evolution
P3348R2 C++26 should refer to C23 not C17 Jonathan Wakely 2025-01-13 2025-01 P3348R1 SG6 Numerics,LEWG Library Evolution
P3351R2 views::scan Yihe Li 2025-01-12 2025-01 P3351R1 SG9 Ranges
P3367R3 constexpr coroutines Hana Dusíková 2025-01-06 2025-01 P3367R2 EWG Evolution,LWG Library
P3373R1 Of Operation States and Their Lifetimes Robert Leahy 2025-01-11 2025-01 P3373R0 LEWG Library Evolution
P3374R1 Adding formatter for fpos Liang Jiaming 2025-01-07 2025-01 P3374R0 LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3375R2 Reproducible floating-point results Guy Davidson 2025-01-13 2025-01 P3375R1 SG6 Numerics,EWGI SG17: EWG Incubator
P3385R3 Attributes reflection Aurelien Cassagnes 2025-01-06 2025-01 P3385R2 SG7 Reflection
P3388R1 When Do You Know connect Doesn't Throw? Robert Leahy 2025-01-11 2025-01 P3388R0 LEWG Library Evolution
P3394R1 Annotations for Reflection Daveed Vandevoorde 2025-01-12 2025-01 P3394R0 SG7 Reflection,LEWG Library Evolution,CWG Core
P3395R0 Formatting of std::error_code Victor Zverovich 2024-12-22 2025-01   SG16 Unicode
P3400R0 Specifying Contract Assertion Properties with Labels Joshua Berne 2025-01-09 2025-01   SG21 Contracts,All of WG21
P3402R2 A Safety Profile Verifying Initialization Marc-André Laverdière 2025-01-13 2025-01 P3402R1 SG23 Safety and Security
P3407R1 Make idiomatic usage of `offsetof` well-defined Brian Bi 2025-01-11 2025-01 P3407R0 EWG Evolution
P3411R1 `any_view` Hui Xie 2025-01-11 2025-01 P3411R0 SG9 Ranges,LEWG Library Evolution
P3412R1 String interpolation Bengt Gustafsson 2025-01-12 2025-01 P3412R0 EWGI SG17: EWG Incubator,EWG Evolution
P3420R1 Reflection of Templates Andrei Alexandrescu 2025-01-13 2025-01 P3420R0 SG7 Reflection
P3423R1 Extending User-Generated Diagnostic Messages Yihe Li 2025-01-12 2025-01 P3423R0 EWG Evolution
P3425R1 Reducing operation-state sizes for subobject child operations Lewis Baker 2025-01-13 2025-01 P3425R0 LEWG Library Evolution
P3430R2 simd issues: explicit, unsequenced, identity-element position, and members of disabled simd Matthias Kretz 2025-01-13 2025-01 P3430R1 LEWG Library Evolution
P3431R0 Deprecate const-qualifier on begin/end of views Jonathan Müller 2025-01-13 2025-01   SG9 Ranges
P3439R1 Chained comparisons: Safe, correct, efficient Herb Sutter 2025-01-06 2025-01 P3439R0 EWG Evolution
P3475R1 Defang and deprecate memory_order::consume Hans Boehm 2025-01-11 2025-01 P3475R0 SG1 Concurrency and Parallelism,EWG Evolution,LEWG Library Evolution,CWG Core,LWG Library
P3477R2 There are exactly 8 bits in a byte JF Bastien 2025-01-11 2025-01 P3477R1 LEWG Library Evolution,CWG Core
P3480R3 std::simd is a range Matthias Kretz 2025-01-13 2025-01 P3480R2 LEWG Library Evolution
P3481R1 std::execution::bulk() issues Lucian Radu Teodorescu 2025-01-13 2025-01 P3481R0 SG1 Concurrency and Parallelism,LEWG Library Evolution
P3491R1 define_static_{string,object,array} Barry Revzin 2025-01-12 2025-01 P3491R0 EWG Evolution,LEWG Library Evolution
P3496R0 Immediate-Escalating Expressions Barry Revzin 2025-01-05 2025-01   EWG Evolution,LEWG Library Evolution
P3499R0 Exploring strict contract predicates Lisa Lippincott 2025-01-13 2025-01   SG21 Contracts,EWG Evolution
P3500R0 Are Contracts "safe"? Timur Doumler 2025-01-13 2025-01   EWG Evolution
P3501R0 The ad-dressing of cats S. Davis Herring 2025-01-10 2025-01   EWG Evolution,CWG Core,LWG Library
P3506R0 P2900 Is Still not Ready for C++26 Gabriel Dos Reis 2025-01-13 2025-01   EWG Evolution
P3516R0 Uninitialized algorithms for relocation Louis Dionne 2025-01-13 2025-01   LEWG Library Evolution
P3527R1 Pattern Matching: *variant-like* and `std::expected` Michael Park 2025-01-13 2025-01 P3527R0 EWG Evolution,LEWG Library Evolution
P3533R1 constexpr virtual inheritance Hana Dusíková 2025-01-10 2025-01 P3533R0 EWG Evolution
P3534R0 Avoid UB When Compiling Code That Violates Library Specification Alisdair Meredith 2025-01-13 2025-01   LWG Library
P3541R1 Violation handlers vs `noexcept` Andrzej Krzemieński 2025-01-06 2025-01 P3541R0 SG21 Contracts,SG23 Safety and Security,EWG Evolution
P3546R0 Explicit return type deduction for std::numeric_limits and numbers Thomas Mejstrik 2024-12-19 2025-01   LEWGI SG18: LEWG Incubator
P3547R0 Modeling Access Control With Reflection Dan Katz 2025-01-09 2025-01   SG7 Reflection,LEWG Library Evolution
P3548R0 P1030 `std::filesystem::path_view` forward progress options Niall Douglas 2025-01-13 2025-01   LEWG Library Evolution
P3549R0 Diverging expressions Barry Revzin 2025-01-12 2025-01   EWG Evolution
P3550R0 Imports cannot ... Alisdair Meredith 2025-01-13 2025-01   EWGI SG17: EWG Incubator,LEWGI SG18: LEWG Incubator
P3552R0 Add a Coroutine Lazy Type Dietmar Kühl 2025-01-13 2025-01   SG1 Concurrency and Parallelism,LEWG Library Evolution
P3554R0 Non-transient allocation with vector and basic_string Barry Revzin 2025-01-05 2025-01   EWG Evolution
P3555R0 An infinite range concept Jonathan Müller 2025-01-13 2025-01   SG9 Ranges
P3557R0 High-Quality Sender Diagnostics with Constexpr Exceptions Eric Niebler 2025-01-12 2025-01   LEWG Library Evolution
P3558R0 Core Language Contracts By Default Joshua Berne 2025-01-12 2025-01   SG21 Contracts,SG23 Safety and Security
P3559R0 Trivial relocation: One trait or two? Arthur O'Dwyer 2025-01-08 2025-01   LEWG Library Evolution
P3560R0 Error Handling in Reflection Barry Revzin 2025-01-12 2025-01   EWG Evolution,LEWG Library Evolution
P3561R0 Index based coproduct operations on variant, and library wording Esa Pulkkinen 2025-01-13 2025-01   LEWGI SG18: LEWG Incubator
P3564R0 Make the concurrent forward progress guarantee usable in `bulk` Mark Hoemmen 2025-01-12 2025-01   SG1 Concurrency and Parallelism
P3565R0 Virtual floating-point values S. Davis Herring 2025-01-10 2025-01   SG6 Numerics
P3566R0 You shall not pass `char*` - Safety concerns working with unbounded null-terminated strings Marco Foco 2025-01-13 2025-01   SG23 Safety and Security,LEWG Library Evolution,LWG Library,ARG ABI Review Group
P3567R0 `flat_meow` Fixes Hui Xie 2025-01-11 2025-01   LEWG Library Evolution,LWG Library
P3568R0 break label; and continue label; Jan Schultke 2025-01-12 2025-01   EWGI SG17: EWG Incubator,SG22 Compatibility
P3569R0 Split define_aggregate from Reflection Shafik Yaghmour 2025-01-11 2025-01   EWG Evolution
P3572R0 Pattern matching Bjarne Stroustrup 2025-01-12 2025-01   EWG Evolution
P3573R0 Contract concerns Bjarne Stroustrup 2025-01-12 2025-01   SG21 Contracts,EWG Evolution,LEWG Library Evolution
P3574R0 Constexpr Callables Steve Downey 2025-01-13 2025-01   LEWG Library Evolution,LWG Library
P3575R0 SG14: Low Latency/Games/Embedded/Financial Trading virtual Meeting Minutes 2024/11/13 Michael Wong 2025-01-12 2025-01   SG14 Low Latency
P3576R0 SG19: Machine Learning virtual Meeting Minutes to 2024/11/14-2024/12/12 Michael Wong 2025-01-12 2025-01   SG19 Machine Learning
P3577R0 Requiring a non-throwing system-provided (default) contract-violation handler John Lakos 2025-01-12 2025-01   SG21 Contracts,EWG Evolution
P3578R0 Language Safety and Grandma Safety Ryan McDougall 2025-01-13 2025-01   SG21 Contracts,SG23 Safety and Security,EWG Evolution
P3579R0 Fix matching of non-type template parameters when matching template template parameters Matheus Izvekov 2025-01-13 2025-01   CWG Core
P3580R0 The Naming of Things Alan Talbot 2025-01-13 2025-01   EWG Evolution,LEWG Library Evolution
P3581R0 No, inplace_vector shouldn't have an Allocator Nevin Liber 2025-01-13 2025-01   LEWG Library Evolution
P3582R0 Observed a contract violation? Skip subsequent assertions! Andrzej Krzemieński 2025-01-13 2025-01   SG21 Contracts,EWG Evolution
P3583R0 Contracts, Types & Functions Jonas Persson 2025-01-13 2025-01   SG21 Contracts
P3584R0 Enrich Facade Creation Facilities for the Pointer-Semantics-Based Polymorphism Library - Proxy Mingxin Wang 2025-01-13 2025-01   LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3585R0 allocator_traits::is_internally_relocatable Pablo Halpern 2025-01-13 2025-01   LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3586R0 The Plethora of Problems With Profiles Corentin Jabot 2025-01-13 2025-01   EWG Evolution
P3587R0 Reconsider reflection access for C++26 Lauri Vasama 2025-01-13 2025-01   SG7 Reflection,EWG Evolution
P3588R0 Allow static data members in local and unnamed classes Brian Bi 2025-01-13 2025-01   EWG Evolution
P3589R0 C++ Profiles: The Framework Gabriel Dos Reis 2025-01-13 2025-01   EWG Evolution
P3590R0 Constexpr Coroutines Burdens Daveed Vandevoorde 2025-01-13 2025-01   EWG Evolution,CWG Core

Solving the Puzzle of Trying to Put an Object into a std::optional -- Raymond Chen

RaymondChen_5in-150x150.jpgLast time, we investigated the puzzle of why the compiler wouldn’t let us put an object into a std::optional. It came down to the fact that the object is not copy-constructible, move-constructible, copy-assignable, or move-assignable, so there’s no way to put the temporary object into the std::optional.

Solving the Puzzle of Trying to Put an Object into a std::optional

by Raymond Chen

From the article:

What we have to do is construct the object in place inside the std::optional. And the C++ standard library term for “construct an object inside a container” is “emplace”.

struct Doodad
{
    Doodad();
    ~Doodad();
    std::unique_ptr<DoodadStuff> m_stuff;
};

struct Widget
{
    std::optional<Doodad> m_doodad;

    Widget()
    {
        if (doodads_enabled()) {
            m_doodad.emplace();
        }
    }
};

The parameters to emplace are whatever parameters you would have passed to the Doodad constructor. In our case, we wanted the default constructor, so that means that we pass nothing to emplace().

Court is in session: Top 10 most notorious C and C++ errors in 2024

Every year, we witness the same drama: bugs wreak havoc on our code as if asserting their dominance. But today, the tide turns—it's time for judgment. Let's dive into the most intriguing bugs we've uncovered this year.

Court is in session: Top 10 most notorious C and C++ errors in 2024

by Aleksandra Uvarova

From the article:

The seventh defendant, what are you draggin' behind your back? Show us quickly! Ah! A little thief! Decided to pocket a juicy chunk of code, huh? No chance, we're bringing this to the light. Honestly, we really wanted to paste the full code of the function here—which has almost 400 code lines—to make searching for errors more interesting. However, we don't want to abuse your mouse wheel, so we've included just the most intriguing part.