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); } 

live demo

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

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -