c++ - Using SFINAE to select function based on whether a particular overload of a function exists -
this question has answer here:
i have been trying choose between 2 templated functions based on whether overload operator<<(std::ostream&, const t&) exists.
example:
template <typename t, typename std::enable_if</* ? */, int>::type = 0> std::string stringify(const t& t) { std::stringstream ss; ss << t; return ss.str(); } template <typename t, typename std::enable_if</* ? */, int>::type = 0> std::string stringify(const t& t) { return "no overload of operator<<"; } struct foo { }; int main() { std::cout << stringify(11) << std::endl; std::cout << stringify(foo{}) << std::endl; } is possible? , if so, how solve problem?
there's no need enable_if, use expression sfinae select correct overload when operator<< present.
namespace detail { template<typename t> auto stringify(std::stringstream& ss, t const& t, bool) -> decltype(ss << t, void(), std::string{}) { ss << t; return ss.str(); } template<typename t> auto stringify(std::stringstream&, t const&, int) -> std::string { return "no overload of operator<<"; } } template <typename t> std::string stringify(const t& t) { std::stringstream ss; return detail::stringify(ss, t, true); } the stringify function template delegates 1 of detail::stringify function templates. then, first 1 selected if expression ss << t well-formed. unnamed bool parameter being used disambiguation between 2 detail::stringify implementations. since primary stringify function passes true argument detail::stringify, first 1 better match when operator<< overload present. otherwise second 1 selected.
this expression decltype(ss << t, void(), std::string{}) in trailing return type of first stringify template merits more detailed explanation. here have single expression consisting of 3 sub-expressions separated comma operator.
the first one, ss << t determines whether function template passes template parameter substitution , added overload resolution set. occur if expression well-formed, i.e. if type in question overloads operator<<.
the middle sub-expression, void() doesn't other ensure user-defined operator, not selected (because cannot overload operator, void parameter type).
the third, , rightmost, sub-expression, std::string{} determines return type of detail::stringify function.
Comments
Post a Comment