More details on formatting custom data types in C++20
This article is the fifth in my mini-series on formatting in C++20. The previous posts can be found here:
Advertisement
Rainer Grimm has been working as a software architect, team and training manager for many years. He enjoys writing articles on the programming languages C++, Python and Haskell, but also enjoys speaking frequently at specialist conferences. On his blog Modern C++ he deals intensively with his passion C++.
A multi-value formatter
Point is a class with three members.
// formatPoint.cpp
#include
#include
struct Point {
int x{2017};
int y{2020};
int z{2023};
};
template
struct std::formatter
auto format(Point point, format_context& context) const {
return formatter
std::format(“({}, {}, {})”,
point.x, point.y, point.y), context);
}
};
int main() {
std::cout 25}”, point) 10}”, point.x)
In this case I rely on the standard formatter std::formatter<:string> away. A std::string_view is also possible. std::formatter
internationalization
The formatting functions std::format* and std::vformat* have overloads that also accept locals. These overloads can be used to localize a formatting string.
The following code snippet shows the corresponding overload of std::format:
template
std::string format( const std::locale& loc,
std::format_string
Args&&… args );
To use a specific local, specify L before the data type in the format string. Now you apply the locale every time you call std::format or set it globally with std::locale::global.
In the following example, I explicitly use the German local for every std::format call.
// internationalization.cpp
#include std::locale createLocale(const std::string& localString) { // (1) int main() { std::cout The createLocale (1) function creates the German local. If this fails, it returns the default local, which uses American formatting. I use the German local in (2), (3), (4) and (5). To see the difference, I also applied the std::format calls immediately afterward. Consequently, the location-dependent thousands separator is used for the integer value (2) and the location-dependent decimal point and thousands separator is used for the floating point value (3). Accordingly, the time period (4) and time point (5) use the specified German locale. The following screenshot shows the output of the program. std::formatter and its specializations define the format specification for the chrono library data types as well. Before I write about them, I will dive deeper into C++20’s Chrono extension. (rme) To home page
#include
#include
#include
try {
return std::locale{localString};
}
catch (const std::exception& e) {
return std::locale{“”};
}
}What’s next?