c++ - num_get facet 和 stringstream 转换为 bool 值 - 初始化 bool 值失败?

标签 c++ templates initialization std stringstream

我继承了一个将字符串转换为数值的模板,想应用它转换为 bool 值。我对 stringstream 和 locale 类不是很有经验。我似乎确实出现了一些奇怪的行为,我想知道是否有人可以向我解释一下?

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

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

return num;  
}  

在我尝试 bool 转换之前这一切正常

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,这对流提取没有影响。

导致您出现问题的原因是,在处理 bool 值时,默认情况下流仅识别值 01。要让它们识别名称 truefalse,您需要使用 boolalpha 操纵器将其明确告知流。

解决问题的最好方法是专门为 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;  
}  

请注意,您的更改并未使代码正常工作。对于您使用的单个测试用例,它似乎只是这样做。 根据您的更改,该函数无法从流中读取并返回未初始化的值。由于任何非零值都将被解释为 true,该函数似乎可以工作,但一旦您尝试提取 “false”,您就会看到它失败(该函数仍然返回 true)。

编辑:调整代码以处理数字和字母 bool 值。

关于c++ - num_get facet 和 stringstream 转换为 bool 值 - 初始化 bool 值失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3880927/

相关文章:

c++ - 所有对最短路径

c++ - 当给定 PE 基地址作为参数时,为什么 ZwUnmapViewOfSection() 取消映射整个进程的内存?

c++ - 为什么 C++ 编译器可以将函数声明为 constexpr,而不能是 constexpr?

c++ - C++中枚举数组的初始化

swift - 必须指定 Swift 协议(protocol)中的初始化程序。为什么呢?

c++ - 这个函数发生了什么?

c++ - 它是如何解析的:使用大括号的init列表构造未命名的临时文件

django - 为什么使用 django TemplateTag 标签?

javascript - 当我向下滚动页面时,如何让一个 div 跟随我?

c - 如何使用函数指针数组?