diff --git a/include/fmt/core.h b/include/fmt/core.h index d3e81852..b894399b 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -853,8 +853,8 @@ void make_value(const T*) { } template ::value&& - std::is_enum::value)> + FMT_ENABLE_IF(std::is_enum::value&& + convert_to_int::value)> inline init make_value(const T& val) { return static_cast(val); } @@ -873,6 +873,14 @@ inline init make_value(const T& val) { return val; } +template ::value&& std::is_convertible< + T, int>::value&& is_formattable::value && + !std::is_same::value)> +inline init make_value(const T& val) { + return val; +} + template init make_value( const named_arg& val) { diff --git a/test/core-test.cc b/test/core-test.cc index c489f550..549a87c8 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -442,6 +442,25 @@ TEST(CoreTest, ConvertToInt) { EXPECT_TRUE((fmt::convert_to_int::value)); } +struct convertible_to_int { + operator int() const { return 42; } +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter { + auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + auto format(convertible_to_int, format_context& ctx) -> decltype(ctx.out()) { + return std::copy_n("foo", 3, ctx.out()); + } +}; +FMT_END_NAMESPACE + +TEST(CoreTest, FormatterOverridesImplicitConversion) { + EXPECT_EQ(fmt::format("{}", convertible_to_int()), "foo"); +} + namespace my_ns { template class my_string { public: