What is the correct way to call std::to_chars?

Viewed 1246

I am trying to call std::to_chars on a double. My code doesn't compile on any compiler I have (gcc 10.2, clang 10.0.1).

Minimally reproducible code (or on godbolt):

#include <charconv>
#include <string>
int main() {
    std::string str;
    str.resize(30);
    auto[ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), double(3.5));
}

I compiled with -std=c++17. The error I'm getting is:

On gcc 10.2:

<source>: In function 'int main()':
<source>:7:83: error: call of overloaded 'to_chars(char*, char*, double)' is ambiguous
    7 |     auto[ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), double(3.5));
      |                                                                                   ^
In file included from <source>:1:
/.../gcc-10.2.0/include/c++/10.2.0/charconv:366:1: note: candidate: 'std::to_chars_result std::to_chars(char*, char*, char, int)'
...

and then it lists all candidates.

On clang 10.0.1, it pretty much just tells me:

<source>:7:21: error: no matching function for call to 'to_chars'
    auto[ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), double(3.5));
                    ^~~~~~~~~~~~~

I tried all the overloads with double that are listed on cppreference's page on std::to_chars, they all give different errors, but in the end nothing works.

I do not understand why the overload resolution is not clear when it should be clear, or am I doing something fundamentally wrong here?

I want to add that MSVC does it fine without any errors.

1 Answers

Your use is perfectly fine, and it compiles correctly under MSVC 19. As described in the Microsoft Docs for the <charconv> functions, this requires at least C++17.

As you can see for yourself in The GNU C++ Library Manual, Chapter 1. Status, C++ 2017, the last update regarding P0067R5 (Elementary string conversions, revision 5) was on GCC 8.1, with the comment "only integral types supported".

Similarly, the libc++ C++17 Status, defines P0067R5 as "Partially done".

If you need more evidence that this is a problem with your C++ implementation, look at the include file for your GCC/Clang installation and you will see that it doesn't define the floating-point overloads (they aren't defined for me, with GCC 10.2.1).

Related