Search code examples
c++stringformatc++23

C++ format using raw string literals


Can you use C++20 format() with raw string literals ? error message return by gcc 14.

#include <format>
#include <stdio.h>
#include <string>
using namespace std;

int main(){
    int id=6, sigma_edge_distance=9, width=6, height=9, total=6;
    string buffer = format(R"({"id":{}, "sigma_edge_distance":{}, "width":{}, "height":{}, "total":{}})",
                id, sigma_edge_distance, width, height, total);
    printf("%s", buffer.c_str());
    return 0;
}

error:

prog.cc: In function 'int main()':
prog.cc:9:27: error: call to consteval function 'std::basic_format_string<char, int&, int&, int&, int&, int&>("{\"id\":{}, \"sigma_edge_distance\":{}, \"width\":{}, \"height\":{}, \"total\":{}}")' is not a constant expression
    9 |     string buffer = format(R"({"id":{}, "sigma_edge_distance":{}, "width":{}, "height":{}, "total":{}})",
      |                     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   10 |                                 id, sigma_edge_distance, width, height, total);
      |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from prog.cc:1:
prog.cc:9:27:   in 'constexpr' expansion of 'std::basic_format_string<char, int&, int&, int&, int&, int&>("{\"id\":{}, \"sigma_edge_distance\":{}, \"width\":{}, \"height\":{}, \"total\":{}}")'
/opt/wandbox/gcc-head/include/c++/14.0.1/format:4175:19:   in 'constexpr' expansion of '__scanner.std::__format::_Checking_scanner<char, int, int, int, int, int>::std::__format::_Scanner<char>.std::__format::_Scanner<char>::_M_scan()'
/opt/wandbox/gcc-head/include/c++/14.0.1/format:3917:30:   in 'constexpr' expansion of '((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_on_replacement_field()'
/opt/wandbox/gcc-head/include/c++/14.0.1/format:3960:58: error: call to non-'constexpr' function 'void std::__format::__invalid_arg_id_in_format_string()'
 3960 |               __format::__invalid_arg_id_in_format_string();
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/opt/wandbox/gcc-head/include/c++/14.0.1/format:218:3: note: 'void std::__format::__invalid_arg_id_in_format_string()' declared here
  218 |   __invalid_arg_id_in_format_string()
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Solution

  • You have to use double braces like {{ .. }} in order to use braces inside the format string.

    #include <format>
    #include <cstdio>
    #include <string>
    using namespace std;
    
    int main(){
        int id=6, sigma_edge_distance=9, width=6, height=9, total=6;
        string buffer = format(R"({{ "id": {}, "sigma_edge_distance": {}, "width": {}, "height": {}, "total": {} }})",
                    id, sigma_edge_distance, width, height, total);
        printf("%s", buffer.c_str());
        return 0;
    }