Placeholders and Extended Character Set

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.


Modernes C++ Mentoring

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.

Romeo Cureliuc

Senior Software Developer presso MAGNA

1 周

Interesting ?? Thanks for sharing. Just one remark, considering the condition of “just one using” I’ve not tried yet, but I would expect that we could use also the std::ignore instead of the currently placeholder “_” and not limited to just one time in structure bindings: auto [std::ignore, str, std::ignore] = … Not sure if working ??

回复
Xavier Solé

Senior Software Development Engineer at Scopely

1 周

Amazing ??

Ivan Zoraja

Associate Professor at FESB - Faculty of Electrical Engineering, Mechanical Engineering and Naval Architecture

4 周

Hope, you are doing well !

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了