C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Should std::to_string be deprecated?

From: Jonathan Sweemer <sweemer_at_[hidden]>
Date: Mon, 9 Oct 2023 17:03:47 +0900
You're right, there's no advantage in constraining std::format, and now
that I think about it, there's probably no advantage in constraining a
generic version of std::to_string either, because I think it's more helpful
for users to see a compilation failure related to a missing formatter (from
the constructor of std::format_string) rather than a missing overload of
std::to_string (from the failed constraint).

So something like the following might be all that is needed to make
std::to_string a generic shorthand for single-arg std::format. Note that I
used a universal reference instead of the lvalue reference from your
original reply so that the argument can be forwarded to std::format - does
it make a difference?

template<typename T>
auto to_string(T&& t) {
  return std::format("{}", std::forward<T>(t));
}

This is essentially the same thing that Grzegorz suggested as well, but
personally I prefer putting it in std::to_string because if it's not going
to be deprecated, then it should at least be made more generic.


On Thu, Oct 5, 2023 at 11:22 PM Jonathan Wakely <cxx_at_[hidden]> wrote:

>
>
> On Thu, 5 Oct 2023 at 14:14, Jonathan Sweemer <sweemer_at_[hidden]> wrote:
>
>> That would result in char being printed out as an int value, e.g. 65
>> instead of 'A', which is inconsistent with std::format("{}", 'A'). If there
>> is a generic version of std::to_string then it should produce the same
>> result as std::format, no?
>>
>> By the way, in your earlier email you mentioned the formatable<char>
>> concept
>>
>
> That was a typo for formattable, but yes it's exists since C++23.
>
>
>> to constrain a hypothetical generic version of std::to_string. Does this
>> concept exist already, and if so, why isn't it used on std::format
>> itself, which as far as I can tell, is currently unconstrained?
>>
>
> What would be the advantage of constraining it? There's only one
> std::format function, so either it compiles or it doesn't. You don't need
> to select between different overloads based on constraints. Checking a
> constraint would just make compilation slower.
>
> Constraining it would allow you to test whether std::format can be called
> for a given argument type, but you can already use std::formattable to do
> that (which would be faster to compile than testing whether a function
> constrained with std::formattable can be called).
>
> But the real answer is probably just that the concept was added in C++23
> and std::format was added in C++20, so it couldn't have been constrained
> with a concept that didn't exist yet. I don't see a compelling reason to
> add the constraint now.
>
>
>>
>> On Thu, Oct 5, 2023 at 9:52 PM Jonathan Wakely <cxx_at_[hidden]> wrote:
>>
>>>
>>>
>>> On Thu, 5 Oct 2023, 12:53 Jonathan Sweemer via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> I would say yes, if the general consensus is that std::to_string is
>>>> useful and should not be deprecated, then at least it should be made more
>>>> generic.
>>>>
>>>> The current list of overloads for std::to_string seems a bit arbitrary
>>>> and incomplete to me, with char being the most error-prone example, as it
>>>> happily binds to the overload taking int.
>>>>
>>>> If you know you're dealing with ints, then I agree that std::to_string
>>>> provides a more simple syntax for converting to a string, but in any
>>>> generic code you either have to use std::format (i.e. forget about
>>>> std::to_string), or do something like the following to delegate between the
>>>> two:
>>>>
>>>> template<typename T>
>>>> concept to_stringable =
>>>>
>>>
>>> requires(const T& t) {
>>> { std::to_string(t) } -> std::same_as<std::string>;
>>> };
>>>
>>> std::is_same_v<T, int> ||
>>>> std::is_same_v<T, long> ||
>>>> std::is_same_v<T, long long> ||
>>>> std::is_same_v<T, unsigned> ||
>>>> std::is_same_v<T, unsigned long> ||
>>>> std::is_same_v<T, unsigned long long> ||
>>>> std::is_same_v<T, float> ||
>>>> std::is_same_v<T, double> ||
>>>> std::is_same_v<T, long double>;
>>>>
>>>> template<typename T>
>>>> auto generic_to_string(const T& t) {
>>>> if constexpr (to_stringable<T>) {
>>>> return std::to_string(t);
>>>> } else {
>>>> return std::format("{}", t);
>>>> }
>>>> }
>>>>
>>>> But the to_stringable concept is very brittle to maintain, because new
>>>> overloads might be added in future versions of the standard, so a truly
>>>> generic version of std::to_string would be more desirable in my view.
>>>>
>>>>
>>>> On Thu, Oct 5, 2023 at 4:56 PM Giuseppe D'Angelo via Std-Proposals <
>>>> std-proposals_at_[hidden]> wrote:
>>>>
>>>>> Il 04/10/23 22:38, Victor Zverovich via Std-Proposals ha scritto:
>>>>> > At the very least std::to_string is a useful shorthand notation for
>>>>> > std::format for numeric types.
>>>>> >
>>>>>
>>>>> But this prompts the question: would it would make sense to have a
>>>>> overload `to_string` taking just any formattable type?
>>>>>
>>>>> Thanks,
>>>>> --
>>>>> Giuseppe D'Angelo
>>>>> --
>>>>> Std-Proposals mailing list
>>>>> Std-Proposals_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>>
>>>> --
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>
>>>

Received on 2023-10-09 08:04:00