我继承了一个将字符串转换为数值的模板,想应用它转换为 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 值时,默认情况下流仅识别值 0
和 1
。要让它们识别名称 true
和 false
,您需要使用 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/