TwistedBlizzard
TwistedBlizzard

Reputation: 1006

Is there any generic conversion from std::string to numeric type?

There are many ways to convert strings to numbers in C++: stoi, stod, stof, etc. Just like how std::invoke is a nice way to call any callable, I am looking for a method that converts string value to a generic numeric value.

For instance, instead of something like this:

int x = std::stoi("5");
long y = std::stol("5555555555");

Something like this:

int x = num_convert("55");
long y = num_convert("5555555555");

Is there any standard functionality for what I am trying to do?

Upvotes: 0

Views: 708

Answers (3)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38539

This can be considered as a generic conversion:

#include<sstream>

int main() {
  int x;
  std::stringstream("55") >> x;

  long y;
  std::stringstream("5555555555") >> y;
}

A function can return only a single type, thus long y = num_convert("5555555555") with a regular function is impossible.

One more hack, help the function to deduce the returned type with the unused parameter:

#include <string>

template<typename T>
T num_convert(const char* s, const T&) {
  return static_cast<T>(std::stoll(s));
}

int main() {
  int x = num_convert("55", x);
  long y = num_convert("5555555555", y);
}

Upvotes: 2

phuclv
phuclv

Reputation: 41805

If you have boost then just use

auto x = boost::lexical_cast<short>("5"s);
auto y = boost::lexical_cast<long>("5555555555"s);

Demo on Godbolt

You can also roll out your own lexical_cast like what boost did, if you don't want to use it

For more information read Boost.LexicalCast

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 473537

What you want is not (easily) viable in C++. The return value of a function is defined by the function name and the arguments it is given (ie: the result of overload resolution). Your hypothetical num_convert("55") and num_convert("5555555555") expressions both take the same argument type. Therefore, they must (usually) call the same function which returns the same value.

Thus, the simplest way to achieve what you want would be for such a function to return a proxy object that stores the argument it is given. The proxy would have conversion operators (operator int, operator long, etc) which would perform the actual conversion.

Of course, this means that auto i = num_convert("55") will not actually do the conversion. If the function was given a temporary, i would contain a reference to that temporary. Which means that any uses of i would be broken, since they would reference a temporary whose lifetime has ended.

The standard doesn't have a function like this.

It would be better to write the type explicitly into the call as a template parameter and then use auto deduction instead of using a proxy: auto i = num_convert<int>("55");. The standard has no such function either. But really, there's not much difference between num_convert<int> and stoi, so just use it.

Upvotes: 2

Related Questions