I would like to have a wrapper around std::format
(or fmt::format
) that utilizes compile time checks of the format string if possible (i.e. if the format string is known at compile time) and revert to run time checks if not (i.e. if the format string is only known at runtime). Unfortunately I have no idea how to figure out if a compile time check is possible.
What I would need is something like overloading a method on its consteval
property (what is not possible in C++20 as far as I know) or another way to disambiguate the calls to Format
in the following example code.
#include <iostream>
#include <format>
template<typename... Args>
[[nodiscard]] auto Format(std::format_string<Args...> fmt, Args&&... args)
{
return std::format(fmt, std::forward<Args>(args)...);
}
template<typename... Args>
[[nodiscard]] auto Format(std::string_view fmt, Args&&... args)
{
return std::vformat(fmt, std::make_format_args(args...));
}
std::string foo()
{
return "Foo{}";
}
constexpr inline std::string_view str = "Foo{}";
int main()
{
std::cout << Format("Foo{}", "bar") << std::endl; // should be compile time checked
std::cout << Format(str, "bar") << std::endl; // should be compile time checked
std::cout << Format(foo(), "bar") << std::endl; // should be run time checked
}
I don't think it is possible but you can use fmt::runtime
for cases when the format string is not known at compile time:
constexpr std::string_view str = "Foo{}";
std::cout << fmt::format("Foo{}", "bar"); // compile time checked
std::cout << fmt::format(str, "bar"); // compile time checked
std::cout << fmt::format(fmt::runtime(foo()), "bar"; // run time checked