diff --git a/include/fmt/core.h b/include/fmt/core.h index b607fb0a..7a3829e8 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -333,22 +333,19 @@ struct error_handler { // GCC 4.6.x cannot expand `T...`. #if FMT_GCC_VERSION && FMT_GCC_VERSION < 407 -template struct is_constructible : std::false_type {}; - typedef char yes[1]; typedef char no[2]; -template struct is_default_constructible { - template static yes& test(int (*)[sizeof(new U)]); +template struct is_constructible { + template static yes& test(int (*)[sizeof(new U(declval()))]); template static no& test(...); enum { value = sizeof(test(FMT_NULL)) == sizeof(yes) }; }; #else template struct is_constructible : std::is_constructible {}; -template -struct is_default_constructible : std::is_default_constructible {}; #endif +struct dummy_formatter_arg {}; // Workaround broken is_constructible in MSVC. } // namespace internal /** @@ -506,7 +503,7 @@ template class basic_format_args; // A formatter for objects of type T. template struct formatter { - formatter() = delete; + explicit formatter(internal::dummy_formatter_arg); }; template @@ -632,11 +629,12 @@ template class value { } value(const void* val) { pointer = val; } - template ::type>::value, - int>::type = 0> + template < + typename T, + typename std::enable_if< + !is_constructible::type, + internal::dummy_formatter_arg>::value, + int>::type = 0> explicit value(const T& val) { custom.value = &val; // Get the formatter type through the context to allow different contexts @@ -646,11 +644,12 @@ template class value { custom.format = &format_custom_arg; } - template ::type>::value, - int>::type = 0> + template < + typename T, + typename std::enable_if< + is_constructible::type, + internal::dummy_formatter_arg>::value, + int>::type = 0> explicit value(const T& val) { custom.value = &val; custom.format =