I would like to check if a certain type can be used with std::format
.
This is my naive attempt:
template<typename Object>
concept formattable = requires(const Object & obj)
{
std::format("{}", obj);
};
But this does not work. It basically returns true for all types. Even those that can't be used with std::format.
static_assert(!formattable<std::vector<int>>); // should return false
Why doesn't this work?
CodePudding user response:
Since std::format
is not a constrained function, the expression std::format("{}", obj)
is always well-formed. You might want to do
#include <format>
template<typename T>
concept formattable = requires {
std::format_context::template
formatter_type<std::remove_cvref_t<T>>()
.format(std::declval<T&>(), std::declval<std::format_context&>());
};
which mainly based on the constraints of the basic_format_arg
's constructor in [format.arg].