First look at C++ 23

16.11.2022 20:01 dev

It’s time for a first look at the C++23 standard. A few months ago I wrote a little bit similar article on my previous polish blog. I think, this article will be more complete and will contain more details and informations about more new features.

Multidimensional table operator

Previously we could use the classic table operator. It assumed only one argument.
In classic C tables, the table operator assumed only integer values as an index.

int q = {'a', 'b', 'c', 'd'};

q[0]; // returns first table element – 'a' letter
q[2]; // returns first table element – 'c' letter

Oldschool c-style strings:

const char* text = "Hello world";

text[0]; // returns first table element – 'H' letter
text[7]; // returns first table element – 'o' letter

It was possible to implement table operator for another data structures and It could assuming another type of arguments.
Standard 23 can implement a table operator that can take more than one argument.
It’s possible to implement all with the same type and with different types:

#include <iostream>
#include <string>

class Test {

    template<typename D>
    void operator[](int a, int b, std::string c, D d) {
        std::cout << a <<  "," << b  <<  ","  << c <<  "," << d << std::endl;

    void operator[](int a, int b) {

        std::cout << a << "," << b << std::endl;

int main() {
   Test n;

   n[7,4,"test", &n];

Simplified type aliasing in range variant of for loop

In previous standards we could create and use type alias in a for loop:

for (typedef int type; type item : collection);

C++ 23 gives us simplified and clearer (in my opinion) syntax for this solution:

for (using typ = int; typ element : collection)

Simplified lambda syntax

Previously, we had to use brackets all the time in lambdas – no matter the function passed arguments or not. Now, if we want to use a lambda no arguments, we can use a lambda expression without brackets:

[] {
      std::cout << "Yellow world!" << std::endl;

Fixed-width floating-point types

23rd standard provides fixed width floating-point types:

  • 16-bit with 11 bits of precision and 5 bits of exponent (std::float16_t),
  • 16-bit with 8 bits of precision and 8 bits of exponent (std::bfloat16_t),
  • 32-bit with 24 bits of precision and 8 bits of exponent (std::float32_t),
  • 64-bit with 53 bits of precision and 11 bits of exponent (std::float64_t),
  • 128-bit with 113 bits of precision and 15 bits of exponent (std::float128_t).

All of them you can attach to your code by including stdfloat.

With all of this types you can use letter suffixes. For example std::floatN_t = 0.3fN where N is the number of bits. For type std::bfloat16 type you can use bf16 suffix. Example:

#include <stdfloat>
#include <iostream>
int main() {
	std::float128_t huge{123456789.1234f128};
	std::cout << "huge number:" << huge << std::endl;

That’s all now, I will return to this subject soon.
See you on the next article! :)

Mistakes or problems? Do you have any suggestions? Leave a comment, and I will fix it! Sometimes, my English leaves a little to be desired. I'm still learning! :)