C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Supporting f-strings in C++

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Fri, 13 Oct 2023 16:23:13 +0100
On Fri, 13 Oct 2023, 11:58 Hadriel Kaplan via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> Back in 2019, https://wg21.link/p1819r0 was submitted for "interpolated
> literals". I believe it was reviewed in EWG-Incubator back then, and again
> in 2022. There appears to have been consensus for the author to keep
> working on it generally, but no consensus on the proposal's specific
> details.
>
> I'd like to propose a different solution - but only for the specific idea
> of having f-strings in C++, as opposed to a general string-interpolation
> framework.
>
> I've written up a brief strawman here: https://tinyurl.com/3tr8rv22
>
> The basic idea is to just syntactically replace an f-string with its
> std::format() counterpart, as a new step between phase 6 and 7 of
> translation, right after concatenation of string-literals. I.e., an
> f-string would just be syntactic-sugar for std::format().
>
> More-detailed rules are written in the linked proposal above. It even
> includes a way to add a customization point should that be desired by the
> WG, at which point it's a form of interpolation and could perhaps fully
> replace P1819.
>
> It's arguably a bit hacky, but it should be far simpler than P1819 to
> implement, use, and maybe even standardize.
>
> I'm looking for feedback on whether this is an idea worth pursuing, or
> whether it's a horrible idea and I should never raise it again.
>

I think this is worth pursuing.

I don't care that it's coupled to std::format, that's consistent with
f-strings being coupled to str.format() in Python. If there's a concern
that we'd want to change them later to use std2::format, we could use
f2"{var}" for that, or another prefix. I think the simplicity of your
proposal is an advantage over a more extensive/extensible feature.

I don't really like being able to call functions, I think I'd feel more
comfortable if you could only name lvalues, not use arbitrary expressions.
The workaround isn't great though, e.g. with an immediately invoked lambda
you'd have to use:
[c=calculate()]{ return f"{c}"; }()
instead of:
f"{calculate()}"

How much of the feature's usefulness is lost if it can only refer to
lvalues, not evaluate expressions?

With reflection in C++ I think this could be done as a user defined
literal, using f as a suffix instead of a prefix. But do we want to wait
for that? Maybe. If the proposal was a pure library extension I'd say we
should just do it, but as it requires changes to how source code is
translated, maybe we don't want to make such fundamental changes as a stop
gap that could be replaced by a decent reflection system.

Received on 2023-10-13 15:23:31