fix ADL lookup error for to_string()-ing user-defined classes
fmt::to_string: use fmt::format() instead of format(), because otherwise unrelated free-standing format() function from the printed class namespace could be called. Example of the bug here: https://stackoverflow.com/q/62423981/19905 This commit includes a test as well. Applied against 6.2.1 because current fmt version seems to be broken at the moment for fmt::to_string()-ing user-defined classes.
This commit is contained in:
parent
19bd751020
commit
e8b47c3efb
@ -3336,14 +3336,14 @@ arg_join<internal::iterator_t<const Range>, wchar_t> join(const Range& range,
|
||||
\endrst
|
||||
*/
|
||||
template <typename T> inline std::string to_string(const T& value) {
|
||||
return format("{}", value);
|
||||
return fmt::format("{}", value);
|
||||
}
|
||||
|
||||
/**
|
||||
Converts *value* to ``std::wstring`` using the default format for type *T*.
|
||||
*/
|
||||
template <typename T> inline std::wstring to_wstring(const T& value) {
|
||||
return format(L"{}", value);
|
||||
return fmt::format(L"{}", value);
|
||||
}
|
||||
|
||||
template <typename Char, std::size_t SIZE>
|
||||
|
||||
@ -2043,9 +2043,31 @@ TEST(FormatTest, DynamicFormatter) {
|
||||
"precision not allowed for this argument type");
|
||||
}
|
||||
|
||||
namespace unrelated {
|
||||
|
||||
struct qwe{};
|
||||
|
||||
std::string format(const char * /*fmt*/, const qwe &) {
|
||||
// Return distinct string on purpose to check whether fmt used
|
||||
// this format() via ADL by mistake
|
||||
return "{unrelated free-standing format() function discovered by ADL by mistake}";
|
||||
}
|
||||
} // namespace unrelated
|
||||
|
||||
template<>
|
||||
struct fmt::formatter<unrelated::qwe> {
|
||||
template<typename ParseContext>
|
||||
auto parse(ParseContext & ctx) -> decltype(ctx.begin()) { return ctx.begin(); }
|
||||
template<typename FormatContext>
|
||||
auto format(const unrelated::qwe &, FormatContext & ctx) -> decltype(ctx.out()) {
|
||||
return fmt::format_to(ctx.out(), "[qwe]");
|
||||
}
|
||||
};
|
||||
|
||||
TEST(FormatTest, ToString) {
|
||||
EXPECT_EQ("42", fmt::to_string(42));
|
||||
EXPECT_EQ("0x1234", fmt::to_string(reinterpret_cast<void*>(0x1234)));
|
||||
EXPECT_EQ("[qwe]", fmt::to_string(unrelated::qwe{}));
|
||||
}
|
||||
|
||||
TEST(FormatTest, ToWString) { EXPECT_EQ(L"42", fmt::to_wstring(42)); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user