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

Time:08-28

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?

CodePudding user response:

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

CodePudding user response:

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.

CodePudding user response:

If you have boost then just use

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

("5555555555"s); std::cout << x << !' !' << y << !'\n!'; } '),l:'5',n:'0',o:'C++ source #1',t:'0')),k:37.698671892009585,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang1400,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c++,libs:!((name:boost,ver:'179')),options:'-O2',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64 clang 14.0.0 (C++, Editor #1, Compiler #1)',t:'0')),header:(),k:62.30132810799042,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64 gcc 12.2',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output of x86-64 clang 14.0.0 (Compiler #1)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:62.30132810799042,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4" rel="nofollow noreferrer">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

  • Related