我有这堂课:
template<typename T> class Parser
{
public:
Parser() : count(0) {}
virtual void parse(const string&);
void get_token(void);
private:
T result;
char token;
string expression;
int count;
};
现在该课程不是通用的,如果说result
,double
,我会用这种方法来检测数字。
while((strchr("1234567890.",token))
{
/* add token to a "temp" string */
/* etc. etc. */
}
result = atof(temp.c_str());
但由于result
是通用的,我无法使用atof
和atoi
等任何方法。
我该怎么办?
答案 0 :(得分:6)
Boost内置了此功能:
#include <boost/lexical_cast.hpp>
void Parser<T>::get_token() {
std::string token = ...;
result = boost::lexical_cast<T>(token);
}
根据需要添加异常处理。
或者,也许你不想出于某种原因使用Boost:
void Parser<T>::get_token() {
std::string token = ...;
std::stringstream ss;
ss << token;
ss >> result;
}
根据需要检查ss
的错误状态。
可以在this related question找到更广泛的答案,但它仅专门讨论int
。
答案 1 :(得分:1)
另一种基于通用模板的Numeric To String转换器。它需要int
s和double
s。
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
template <class T>
inline std::string Numeric_To_String (const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
int main(int argc, char *argv[])
{
int i = 9;
double d = 1.2345;
string s;
cout <<"Generic Numeric_To_String( anyDatatype ) \n\n";
s = Numeric_To_String( i );
cout <<"int i to string : "<< s <<" "<< endl;
s = Numeric_To_String( d );
cout <<"double d to string : "<< s <<" "<< endl;
cout <<" \n";
return 0;
}
答案 2 :(得分:0)
如果您只有一手牌要解析,可以使用模板专业化:
template<>
void Parser<int>::parse(const string&)
{
result = atoi(string.c_str());
}
template<>
void Parser<float>::parse(const string&)
{
result = atof(string.c_str());
}
... 但这只有在你实现所需的每一次转换时才有效。
答案 3 :(得分:0)
在C ++ 17中,您可以使用模板化的std::from_chars
。
https://en.cppreference.com/w/cpp/utility/from_chars
#include <charconv>
#include <iostream>
template <typename Number>
auto stringTo(std::string_view str)
{
Number number;
std::from_chars(str.data(), str.data() + str.size(), number);
return number;
}
int main()
{
const auto str = std::string("42");
std::cout << stringTo<long>(str) << '\n';
std::cout << stringTo<double>(str) << '\n';
}
检查std::from_chars
的返回值以检测错误。
const auto result = std::from_chars(...);
if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range)
{
std::cout << "string to number error" << '\n';
}
更多信息和示例:https://www.bfilipek.com/2018/12/fromchars.html
GCC和clang尚不支持std::from_chars
的浮点版本(2019年8月)。