The way libfmt (and std::format
) do it is by passing a custom class instead of std::string_view
, with a consteval
constructor accepting a string. Said constructor runs at compile-time and can e.g. throw (or do something else) to cause a compile-time error.
But this approach doesn't let you do this:
create a
std::tuple
based on thei
ands
s in the provided string
This requires passing the string as a template parameter:
template <std::size_t N>struct ConstString{ char value[N]{}; constexpr ConstString() {} constexpr ConstString(const char (&str)[N]) { std::copy_n(str, N, value); } [[nodiscard]] constexpr std::string_view view() const { return std::string_view(value, value + N - 1); }};template <ConstString S>void foo();int main(){ foo<"blah">();}
Or with a slightly different call syntax:
template <ConstString>struct ConstStringTag {};template <ConstString S>[[nodiscard]] ConstStringTag<S> constexpr operator""_c() {return {};}template <ConstString S>void foo(ConstStringTag<S>);int main(){ foo("blah"_c);}