Placeholders and Extended Character Set

Placeholders are a nice way to highlight variables that are no longer needed. Additionally, the character set of C++26 will be extended.

Placeholders

Structured bindings are a C++17 feature that allows you to bind multiple variables to the elements of a structured object.

The following program demonstrates using tuples and structured bindings to return and unpack multiple values from a function.

// placeholder1.cpp

#include <tuple>
#include <string>
#include <iostream>

// Function that returns three values
std::tuple<int, std::string, double> getThreeValues() {
    int intValue = 42;
    std::string strValue = "example";
    double doubleValue = 3.14;
    return std::make_tuple(intValue, strValue, doubleValue);
}

int main() {

    // Retrieve the three values using structured binding
    auto [intValue, strValue, doubleValue] = getThreeValues();

    // Print the values
    std::cout << "Integer: " << intValue << '\n';
    std::cout << "String: " << strValue << '\n';
    std::cout << "Double: " << doubleValue << '\n';

}

The function getThreeValues is defined to return a tuple containing three different types of values: an int, a std::string, and a double. These values are then packed into a tuple using std::make_tuple and returned from the function.

In the main function, the program retrieves the three values returned by getThreeValues using structured bindings. Structured bindings allow the program to unpack the tuple directly into three separate variables: intValue, strValue, and doubleValue. This makes the code more readable and easier to work with than manually unpacking the tuple.

Sometimes, you don’t need all three values from the function getThreeValues.

// placeholder2.cpp

#include <tuple>
#include <string>
#include <iostream>

// Function that returns three values
std::tuple<int, std::string, double> getThreeValues() {
    int intValue = 42;
    std::string strValue = "example";
    double doubleValue = 3.14;
    return std::make_tuple(intValue, strValue, doubleValue);
}

int main() {

    // Retrieve the three values using structured binding
    auto [_, strValue, doubleValue] = getThreeValues();

    // Print the values
    std::cout << "String: " << strValue << '\n';
    std::cout << "Double: " << doubleValue << '\n';

}

This time, the intValue from the function getThreeValues is not needed in the subsequent code. By convention, I bind it to the underline.

At the same time, this means that the compiler does not issue a warning because the variable _ is not used:

Unfortunately, the intuitive _ can only be used once as an identifier. This changes with C++26. Now, it can be used as often as required.

// placeholder3.cpp

#include <tuple>
#include <string>
#include <iostream>

// Function that returns three values
std::tuple<int, std::string, double> getThreeValues() {
    int intValue = 42;
    std::string strValue = "example";
    double doubleValue = 3.14;
    return std::make_tuple(intValue, strValue, doubleValue);
}

int main() {

    // Retrieve the three values using structured binding
    auto [_, strValue, _] = getThreeValues();

    // Print the values
    std::cout << "String: " << strValue << '\n';
    
}

In this variant, neither the intValue nor the doubleValue from the function getThreeValues is not required. I consistently use two underscores.

Rainer D 6 P2 500x500

 

Rainer D 6 P2 500x500Modernes C++ Mentoring

  • "Fundamentals for C++ Professionals" (open)
  • "Design Patterns and Architectural Patterns with C++" (open)
  • "C++20: Get the Details" (open)
  • "Concurrency with Modern C++" (open)
  • "Generic Programming (Templates) with C++": October 2024
  • "Embedded Programming with Modern C++": October 2024
  • "Clean Code: Best Practices for Modern C++": March 2025
  • Do you want to stay informed: Subscribe.

     

    Extended Character Set

    Three new characters are available in the basic character set:

    The following program uses all three of them for raw string literals.

    // extendedCharacterset.cpp
    
    #include <iostream>
    
    int main() {
    
        std::cout << '\n';
    
        auto raw1 = R"@(Hello\n)@";    
        auto raw2 = R"$(Hello\t)$";    
        auto raw3 = R"`(Hello\b)`";
        
        std::cout << "raw1: " << raw1 << '\n';    
        std::cout << "raw2: " << raw2 << '\n';    
        std::cout << "raw3: " << raw3 << '\n';
    
        std::cout << '\n';
    
    }
    

    The program then defines three raw string literals: raw1, raw2, and raw3. Raw string literals in C++ are enclosed in R"delimiter(...)delimiter", where delimiter can be any sequence of characters. This allows the string to contain special characters like \n, \t, and \b without needing to escape them.

    • raw1 is defined as R"@(Hello\n)@", which contains the text Hello\n without interpreting \n as a newline character.
    • raw2 is defined as R"$(Hello\t)$“, which contains the text Hello\t without interpreting \t as a tab character.
    • raw3 is defined as R"`(Hello\b)`", which contains the text Hello\b without interpreting \b as a backspace character.

    Finally, here’s the output of the program:

    What’s next?

    The core language of C++26 still offers improvements, such as pack indexing. I will write about this in the next blog post.

    Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Stephen Kelley, Kyle Dean, Tusar Palauri, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, Marco Parri Empoli, Philipp Lenk, Charles-Jianye Chen, Keith Jeffery, Matt Godbolt, and Honey Sukesan.

    Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.

    My special thanks to Embarcadero
    My special thanks to PVS-Studio
    My special thanks to Tipi.build 
    My special thanks to Take Up Code
    My special thanks to SHAVEDYAKS

    Modernes C++ GmbH

    Modernes C++ Mentoring (English)

    Do you want to stay informed about my mentoring programs? Subscribe Here

    Rainer Grimm
    Yalovastraße 20
    72108 Rottenburg

    Mobil: +49 176 5506 5086
    Mail: schulung@ModernesCpp.de
    Mentoring: www.ModernesCpp.org

    Modernes C++ Mentoring,