4

I would like to use the fmt library to create a string_view from my format args. There is plenty documented about passing in a compile-time string as the format string, however, I want to output a compile-time string, so that I may use it in other static parts of my code. Is there a way to do this? So far, all the functions I have seen return a std::string; I also tried format_to, but it seems to be explicitly disabled for a string_view iterator (which I am assuming wouldn't work compile-time anyway, as it's mutating). It may be simple and I'm just looking in the wrong places, I don't know.

I would like to be able to do something akin to the following:

consteval std::string_view example(unsigned i){
    return fmt::something<std::string_view>("You sent {}"sv, i);
}

So far, this library seems to provide what I need, but, it would be advantageous to avoid a second dependency.

stellarpower
  • 332
  • 3
  • 13
  • 7
    `std::string_view` is non-owning. Thus it can't be a recipient of a format because there is no backing store or the backing store would be ephemeral. That would lead to a dangling reference in effect which is *bad™*. – Mgetz Feb 22 '22 at 13:32
  • This must be why I couldn't use it this way in my first attempt; IIRC it looked like the overload was explicitly deleted/disabled for string_view. I didn't get round to trying array. – stellarpower Feb 24 '22 at 03:48

1 Answers1

7

You can do this with format string compilation (FMT_COMPILE):

#include <fmt/compile.h>

consteval auto example(unsigned i) -> std::array<char, 16> {
  auto result = std::array<char, 16>();
  fmt::format_to(result.data(), FMT_COMPILE("You sent {}"), i);
  return result;
}

constexpr auto result = example(42);

This gives an array rather than a string_view but you can make one from the other.

Godbolt: https://godbolt.org/z/TqoEfTfWs

vitaut
  • 49,672
  • 25
  • 199
  • 336
  • I am interested if array would behave as well as a compile-time string. I have seen string_view recommended for this, I believe it satisifes literal-type requirements, yet as mentioned in a comment above, it is non-owning and serves a dual-purpose of providing a view over a runtime string. Also, it would be useful to e.g. concatenate compile-time strings, which array wouldn't necessarily be aware of. – stellarpower Feb 24 '22 at 03:45
  • However, array does meet many of these requirements, and in many ways is simpler. The main question I would want to know is if used in a literal fashion, if the data would still be allocated. For my situation, I need to pre-allocate the strings and store as static data for fast lookup, but, if someone wants to create constant strings and then discard a number, and not allocate the storage that array is backing, except where it is lazily used, then I'd be intrigued to see how well it performs for their/other use-case/s. – stellarpower Feb 24 '22 at 03:47
  • This solved my problem anyway, so marking as the solution. – stellarpower Feb 24 '22 at 03:47