The presence of a to_string_view(T) function (visible by ADL as usual) breaks dynamic_format_arg_store.push_back(T).
https://gcc.godbolt.org/z/j1xdje
The problem is probably just the use of detail::is_string<T> in the private stored_type<T> metafunction.
Anything with a to_string_view(T) will have a detail::is_string<T>::value == true.
https://github.com/fmtlib/fmt/blob/master/include/fmt/args.h#L97-L99
#include <fmt/args.h>
#include <fmt/format.h>
#include <iostream>
#include <string>
#include <string_view>
struct UserType {
std::string name;
#ifdef HAS_TO_STRING_VIEW
friend std::string_view to_string_view(const UserType& ut) { return ut.name; }
#endif
};
template <>
class fmt::formatter<UserType> : fmt::formatter<std::string_view> {
using Base = fmt::formatter<std::string_view>;
public:
using Base::parse;
template <typename FC>
auto format(const UserType& ut, FC&& fc) {
return Base::format(ut.name,fc);
}
};
void print(const std::string& s) { std::cout << s << std::endl; }
int main() {
UserType ut{"Alice"};
print(format(FMT_STRING("sanity check: {}"), ut)); // works
{
fmt::dynamic_format_arg_store<fmt::format_context> args;
args.push_back(fmt::arg("userRef", ut)); // std::string(ut) fails
print(vformat(FMT_STRING("named: {userRef}"), args));
}
{
fmt::dynamic_format_arg_store<fmt::format_context> args;
args.push_back(fmt::arg("userRef", std::cref(ut))); // std::string(ut) fails
print(vformat(FMT_STRING("named,cref: {userRef}"), args));
}
}
When we build with -DHAS_TO_STRING_VIEW, we get a cascade of failure:
The salient part is here:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/args.h: In instantiation of 'constexpr fmt::v7::detail::dynamic_arg_list::typed_node<T>::typed_node(const Arg&) [with Arg = UserType; T = std::__cxx11::basic_string<char>]':
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/args.h:54:52: required from 'const T& fmt::v7::detail::dynamic_arg_list::push(const Arg&) [with T = std::__cxx11::basic_string<char>; Arg = UserType]'
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/args.h:201:64: required from 'void fmt::v7::dynamic_format_arg_store<Context>::push_back(const fmt::v7::detail::named_arg<typename Context::char_type, T>&) [with T = UserType; Context = fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>; typename Context::char_type = char]'
<source>:33:43: required from here
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/args.h:43:57: error: no matching function for call to 'std::__cxx11::basic_string<char>::basic_string(const UserType&)'
43 | FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}
| ^
The presence of a
to_string_view(T)function (visible by ADL as usual) breaksdynamic_format_arg_store.push_back(T).https://gcc.godbolt.org/z/j1xdje
The problem is probably just the use of
detail::is_string<T>in the privatestored_type<T>metafunction.Anything with a
to_string_view(T)will have adetail::is_string<T>::value == true.https://github.com/fmtlib/fmt/blob/master/include/fmt/args.h#L97-L99
When we build with
-DHAS_TO_STRING_VIEW, we get a cascade of failure:The salient part is here: