num_get facet和stringstream转换为boolean - 失败并初始化布尔值? [英] num_get facet and stringstream conversion to boolean - fails with initialised boolean?

查看:219
本文介绍了num_get facet和stringstream转换为boolean - 失败并初始化布尔值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已继承一个模板,将字符串转换为数值,并希望将其应用于转换为 boolean 。我对stringstream和locale类不是很有经验。我似乎有一些奇怪的行为,我想知道是否有人可以向我解释它。

 模板< T> T convertFromString(const string& str)const {

std :: stringstream SStream(str);
T num = 0;
SStream>> num;

return num;
}

这样工作正常,直到我尝试布尔转换

  string str1(1); 
int val1 = convertFromString< int>(str1); // ok
string str2(true);
bool val2 = convertFromString< bool>(str2); // val2 is _false_

我花了一些时间跟踪问题。我已经确认语言环境的truename()返回true。



问题似乎是变量 num 的初始化。我可以改变模板到这个和它的工作原理:

  template< typename T& T convertFromString(const string& str)const {

std :: stringstream SStream(str);
T num; //< ----------------------- Changed here
SStream>> num;

return num;
}
String str2(true);
bool val2 = convertFromString< bool>(str2); // val2 is _true_

为什么它工作?我接受用'0'初始化一个bool是错误的,但为什么会导致 SStream>> num 转换失败?


<初始化一个带有0的bool将可靠地设置为false,这对流提取没有影响。



导致您的问题是,默认情况下,流处理布尔值时,流只能识别值 0 1 。要让他们识别名称 true false ,您需要明确地告诉流与 boolalpha 操纵器。



解决你的问题的最好方法是专门为bool模板:

 模板<> bool convertFromString< bool>(const string& str)const {
std :: stringstream SStream(str);
bool val = false;
SStream>> val;
if(SStream.fail())
{
SStream.clear();
SStream>> boolalpha> val;
}
return Val;
}

请注意,您的更改不是 工作。它似乎这样做对于你使用的单个测试用例。
根据您的更改,函数无法从流中读取,并返回未初始化的值。由于任何非零值将被解释为true,函数似乎工作,但是一旦你尝试提取false,你会看到它失败



修改:修改代码以处理数字和Alpha bool。


I have inherited a template to convert a string to a numerical value, and want to apply it to convert to boolean. I am not very experienced with the stringstream and locale classes. I do seem to be getting some odd behaviour, and I am wondering if someone could please explain it to me?

template<typename T> T convertFromString( const string& str ) const {

std::stringstream SStream( str );  
T num = 0; 
SStream >> num;

return num;  
}  

This works fine until I try the boolean conversion

string str1("1");
int val1 = convertFromString<int>(str1); // ok
string str2("true");
bool val2 = convertFromString<bool>(str2); // val2 is _false_

I spent some time tracking down the problem. I have confirmed that the locale's truename() returns "true".

The problem seems to be with the initialisation of the variable num. I can change the template to this and it works:

template<typename T> T convertFromString( const string& str ) const {

std::stringstream SStream( str );  
T num;  // <----------------------- Changed here
SStream >> num;

return num;  
}  
string str2("true");
bool val2 = convertFromString<bool>(str2); // val2 is _true_

Why does it work? I accept that initialising a bool with '0' is wrong, but why would this cause the SStream>>numconversion to fail?

解决方案

Initialising a bool with 0 will reliably set it to false, and this has no effect on the stream extraction.

What is causing your problem is that streams by default only recognize the values 0 and 1 when dealing with booleans. To have them recognize the names true and false, you need to tell that explicitly to the stream with the boolalpha manipulator.

The best way to solve your problems is to specialize the template for bool:

template<> bool convertFromString<bool>( const string& str ) const {
  std::stringstream SStream( str );  
  bool val = false;
  SStream >> val;
  if( SStream.fail() )
  {
    SStream.clear(); 
    SStream >> boolalpha >> val; 
  }    
  return val;  
}  

Note that your change did not make the code work. It just appeared to do so for the single testcase you used. With your change, the function failed to read from the stream and returned an uninitialised value. As any non-zero value will be interpreted as true, the function appears to work, but as soon as you try to extract "false", you will see it fail (the function still returns true).

Edit: Adapted the code to handle both numeric and alpha bools.

这篇关于num_get facet和stringstream转换为boolean - 失败并初始化布尔值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆