trailing decltype in function templates

suggest change

One of constraining function is to use trailing decltype to specify the return type:

namespace details {
   using std::to_string;

   // this one is constrained on being able to call to_string(T)
   template <class T>
   auto convert_to_string(T const& val, int )
       -> decltype(to_string(val))
   {
       return to_string(val);
   }

   // this one is unconstrained, but less preferred due to the ellipsis argument
   template <class T>
   std::string convert_to_string(T const& val, ... )
   {
       std::ostringstream oss;
       oss << val;
       return oss.str();
   }
}

template <class T>
std::string convert_to_string(T const& val)
{
    return details::convert_to_string(val, 0);
}

If I call convert_to_string() with an argument with which I can invoke to_string(), then I have two viable functions for details::convert_to_string(). The first is preferred since the conversion from 0 to int is a better implicit conversion sequence than the conversion from 0 to ...

If I call convert_to_string() with an argument from which I cannot invoke to_string(), then the first function template instantiation leads to substitution failure (there is no decltype(to_string(val))). As a result, that candidate is removed from the overload set. The second function template is unconstrained, so it is selected and we instead go through operator<<(std::ostream&, T). If that one is undefined, then we have a hard compile error with a template stack on the line oss << val.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


SFINAE:
* void_t
* trailing decltype in function templates

Table Of Contents
8 Arrays
11 Loops
39 Streams
51 Unions
56 Lambdas
60 SFINAE
62 RAII
67 Sorting
84 RTTI
87 Scopes
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype