C++ Logo

std-proposals

Advanced search

[std-proposals] Proposal to add f-strings to C++ as an improvement of string formatting

From: Yuri <yuri_at_[hidden]>
Date: Tue, 27 Dec 2022 22:59:19 -0800
**********************************
** Problem that f-strings solve **
**********************************

String formatting in C++ requires more characters than minimally necessary.

There are two major ways to format complex strings in C++:
1. using operator<<, for example:
    std::cout << "threshold is " << threshold << ", time is now " <<
time() << std::endl; (1)
2. using std::format, for example:
    std::cout << std::format("threshold is {}, time is now {}",
threshold, time()) << std::endl; (2)

Both ways have problems: they require more characters than minimally
necessary to perform the task of formatting. The second way also separates
variables and their print locations, which makes it more error prone.

It's common to need to do a lot of complex message printing for programs,
when various values or expressions need to be incorporated into the message.
C++ code in these cases is less expressive than it can be.

**********************
** Proposed feature **
**********************

Introduce a special kind of string in C++: f-string.

f-string begins with the 'f' character (f"string" or Lf"string"). When an
f-string is encountered it is interpreted in the same way as regular strings
with this exception:

> The '{' character is assumed to begin an rvalue expression. Compiler
would
> change context after '{' and would begin to parse the rvalue, expecting
> to find the closing '}' after the rvalue ends. The closing '}' would
restore
> the string context. In order for '{' and '}' characters to appear in
> an f-string they should be escaped, \{ and \}.

Compiler would replace all "...{<rvalue>}..." tokens in f-strings with
"..." << <rvalue> << "...", allowing them to be further processed in the
same
way as an operator<<-based print construct.

This way forming complex strings in C++ would become simpler. The above
example
would look like:
std::cout << "threshold is {threshold}, time is now {time()}" <<
std::endl; (3)
This is more readable and intuitive than both (1) and (2).

*****************
** Limitations **
*****************

(1) rvalues should be printable with operator<<.
(2) for simplicity macros wouldn't be allowed in rvalues embedded in
f-strings.

*************************************
** Affected elements of toolchains **
*************************************

* C++ compiler
* Syntax highlighters in editors and other software

**************
** Benefits **
**************

f-strings would simplify string formatting and allow to make string
formatting
code as simple as possible. This would make printing code less error
prone, and
would make it much easier to read.

*****************************
** What inspired this idea **
*****************************

(1) While writing a lot of C++ code with many complex messages incorporating
     a lot of various values I was thinking that it got to be a shorter and
     easier way of doing this.
(2) While seeing f-strings in Python recently I realized that C++ can also
     greatly benefit from this feature.

*************
** Example **
*************

This code would be legal C++ code with f-strings:

#include <chrono>
#include <ctime>
#include <iostream>
#include <pwd.h>
#include <unistd.h>

using namespace std;

int main() {
         auto now =
chrono::system_clock::to_time_t(chrono::system_clock::now());
         cout << "Hello {getpwuid(geteuid())->pw_name}"
                 ", the time now is {ctime(&now)}." << endl;
}



Thank you,
Yuri Victorovich

Received on 2022-12-28 06:59:22