You wouldn't gain much because in an expression like
int x = sto("1");
There is no (easy) way to deduce the desired type for the template parameter. You would have to write
int x = sto<int>("1");
which to some extend defeats the purpose of providing a generic function. On the other hand, a
template<typename T> void sto(std::string x,T& t);
would be of good use as you realized. In C++17 there is std::from_chars, which does more or less exactly that (it is no template but a set of overloads and it takes pointers to chars instead of a string, but thats only minor details).
PS There is no easy way to deduce the desired type in the above expression, but there is a way. I dont think the core of your question was exactly the signature you asked for, and I dont think the following is a good way to implement it, but I knew that there is a way to make the above int x = sto("1"); compile and I was curious to see it in action.
#include <iostream> #include <string> struct converter { const std::string& x; template <typename T> operator T() { return 0;} }; template <> converter::operator int() { return stoi(x); } template <> converter::operator double() { return stod(x); } converter sto(const std::string& x) { return {x}; } int main() { std::string s{"1.23"}; int x = sto(s); double y = sto(s); std::cout << x << " " << y; }
This works as intended, but it has severe downsides, maybe most importantly it allows to write auto x = sto(s);, ie it is easy to use wrong.