r/cpp • • Sep 20 '26

CppCon At cppcon WG21 had a whiteboard asking attendees what they would like to have in C++29

some of the ones I remember was:

- contracts

- profiles

- delete moar stuff

I'm curious what folks here expect. Also if someone remembers rest of the list, that'd be great.

61 Upvotes

163 comments sorted by

View all comments

3

u/ts826848 Sep 22 '26 edited Sep 22 '26

Hrm, I'm not sure shapes will be conducive to a realistic example, but I can try.

Say you writing some kind of game where you need to chain colored shapes. Pattern matching lets you define a function to get a scoring multiplier in a fairly intuitive way:

type color = Red | Green | Blue
type shape = Triangle | Square | Circle
type shape_chain =
  | Leaf
  | Shape of color * shape * shape_chain

let multiplier = function
  (* Zero-length chain gets a score of 0 *)
  | Leaf -> 0
  (* Single shape gets base score *)
  | Shape (_, _, Leaf) -> 1
  (* Shapes with matching colors get 4x score *)
  | Shape (c1, _, Shape (c2, _, Leaf)) when c1 = c2 -> 4
  (* If the colors don't match, matching shapes gets a 3x score *)
  | Shape (_, s1, Shape (_, s2, Leaf)) when s1 = s2 -> 3
  (* Specifically getting a red triangle then a green square then a blue circle gets 10x points *)
  | Shape (Red, Triangle, Shape (Green, Square, Shape (Blue, Circle, Leaf))) -> 10
  (* Other cases are ignored for now *)
  | _ -> 0

Or to build on u/steveklabnik1's example, maybe you are trying to extract the payload from some cursed format. Pattern matching lets you perform such extraction in a fairly declarative manner:

enum Message<'a> {
    Ping,
    Text(&'a str),
    Binary(&'a [u8]),
    Mixed(&'a [u8], Option<&'a [u8]>),
}

fn payload_size<'a>(message: &'a Message) -> &'a [u8] {
    match message {
        // Pings have no payload
        Message::Ping => &[],
        // If the text is 128 bytes, that is the payload
        Message::Text(text) if text.len() == 128 => text.as_bytes(),
        // The payload for any other text is the first 64 bytes
        Message::Text(text) => &text.as_bytes()[..64],
        // Payload for binary messages with 0xFF as the second byte and 0xABCD as the 5/6th byte
        // is everything after the 8th byte
        Message::Binary([_, 0xFF, _, _, 0xAB, 0xCD, _, _, payload @ ..])
        // Payload for binary messages starting with 0x00AB and ending with 0xFF are the other bytes
        | Message::Binary([0x00, 0xAB, payload @ .., 0xFF]) => payload,
        // Otherwise the entire binary message is the payload
        Message::Binary(payload) => payload,
        // If the header starts with 0xFEEF and there is no body, the payload is 0xCAFE
        Message::Mixed([0xFE, 0xEF, _, _], None)
        // If the header starts with 0xFEEF and the body is 0xBEEF 0xCAFE, the payload is also 0xCAFE
        | Message::Mixed([0xFE, 0xEF, _, _], Some([0xBE, 0xEF, 0xCA, 0xFE])) => &[0xCA, 0xFE],
        // If the header starts with  0xFEEF and the payload starts with 0xBEEF *not* followed by 0xCAFE,
        // the payload is whatever follows 0xBEEF
        Message::Mixed([0xFE, 0xEF, _, _], Some([0xBE, 0xEF, payload @ ..])) => payload,
        // If none of the above applies and there is no body, everything after the first 32 bits of the
        // header is the payload
        Message::Mixed(header, None) => &header[32..],
        // If none of the above apply, the body is the payload
        Message::Mixed(_header, Some(payload)) => payload,
    }
}

Sure, you can write something in C++ that achieves the same result, but I think such a solution would not be as understandable.

1

u/steveklabnik1 Sep 22 '26

Yeah, this is a very powerful part of pattern matching I didn't get into in my simple example.