4

I want to create a nice table in stdout. The table has a lot of headers that are mainly compiletime strings. For example:

std::cout << fmt::format("|{0:-^80}|\n", "File Information");

The above prints:

|-----------------------------File Information------------------------------|

I have lots of different type of fills and align widths. I decided to make some helper functions:

constexpr static
std::string_view
headerCenter(const std::string& text, const int width, const char fill) {

    // build fmt string
    const std::string_view format = "{:" + 'fill' + '^' + toascii(width) + '}';
    return fmt::format(format, text);    
}

I got this error while compiling:

Constexpr function never produces a constant expression

What is it that I am doing wrong, and how to do it correctly?

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
DEKKER
  • 877
  • 6
  • 19
  • I doubt formatting could be done at compile-time. And if you use any run-time variables in the call to `headerCenter` call then it can't be compile-time either. – Some programmer dude May 13 '22 at 06:39
  • There's a syntax error in your code `'fill'` is a multi-byte char. – JHBonarius May 13 '22 at 06:51
  • You also have a problem that you add integer values to pointers. `"any string" + 'x'` doesn't create the string `"any stringx"`, it returns a pointer to `("any string")['x']`. Use e.g. `"any string"s + 'x'` to create a `std::string` for the string and append the character. – Some programmer dude May 13 '22 at 06:56
  • I recall compile time `std::string` is supported after C++ 20. – Louis Go May 13 '22 at 08:11

1 Answers1

3

The type of the format string and the return type of the function cannot be string_view since the format string is constructed dynamically, using string_view will result in a dangling pointer.

In addition, fmt::format requires that the format string must be a constant expression. Instead, you need to use fmt::vformat. This should work

static std::string
headerCenter(const std::string& text, const int width, const char fill) {
  // build fmt string
  std::string format = fmt::format("|{{0:{}^{}}}|", fill, width);
  return fmt::vformat(format, fmt::make_format_args(text));
}

Demo

康桓瑋
  • 33,481
  • 5
  • 40
  • 90