2011-04-08 94 views
1

这会导致由于额外的空格问题:问题的boost ::词汇投

std::string t("3.14 "); 
double d = boost::lexical_cast<double> (t); 

所以,我写了这个

template<typename T> 
T string_convert(const std::string& given) 
{ 
    T output; 
    std::stringstream(given) >> output; 
    return output; 
} 

double d = string_convert<double> (t); 

什么可以是这个问题?有没有更好的办法?更喜欢使用词法转换

回答

6

请注意,您的代码并不总是正确的。例如,如果您执行string_convert<double>("a"),读取操作将失败,并且您将返回output未初始化,导致未定义的行为。

你可以这样做:

template<typename T> 
T string_convert(const std::string& given) 
{ 
    T output; 
    if (!(std::stringstream(given) >> output)) 
    throw std::invalid_argument(); // check that extraction succeeded 

    return output; 
} 

注意上面的代码和Boost的之间的唯一区别是,升压还进行检查,以确保没有流中离开。你应该做的,虽然只是修剪字符串第一:

#include <boost/algorithm/string/trim.hpp> 

std::string t("3.14 "); 
boost::algorithm::trim(t); // get rid of surrounding whitespace 

double d = boost::lexical_cast<double>(t); 
+0

重要的是,上面的'string_convert'模板不只是方便忽略空格:如果还忽略尾随非空白,可能也预示无效值。 'trim'确实更健壮,或者你可以改变'string_convert' ala'char c; std :: stringstream ss(given); if(!(ss >> output)||(ss >> c))...'。 – 2011-04-08 05:44:16

+0

如果你想要一个忽略尾随空格的转换函数,你应该这样做:'std :: stringstream(given); if(!(s >> output >> ws)|| s.get()!= EOF)throw ...' – 2011-04-08 09:41:00

3

Boost::lexical_cast认为尝试转换成功只有如果整个输入转换为输出。也就是说,它基本上和你的string_convert一样,除了在return output之前,它检查stringstream是否还有任何东西,如果有的话,它认为转换“失败”并抛出异常。