you*_*ing 2 c++ templates initialization std stringstream
我继承了一个模板来将字符串转换为数值,并希望将其应用于转换为布尔值.我对stringstream和locale类不太熟悉.我似乎得到了一些奇怪的行为,我想知道是否有人可以向我解释一下?
template<typename T> T convertFromString( const string& str ) const {
std::stringstream SStream( str );
T num = 0;
SStream >> num;
return num;
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,直到我尝试布尔转换
string str1("1");
int val1 = convertFromString<int>(str1); // ok
string str2("true");
bool val2 = convertFromString<bool>(str2); // val2 is _false_
Run Code Online (Sandbox Code Playgroud)
我花了一些时间来追查问题.我已经确认locale的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_
Run Code Online (Sandbox Code Playgroud)
它为什么有效?我接受用'0'初始化一个bool是错误的,但为什么这会导致SStream>>num转换失败?
使用0初始化bool将可靠地将其设置为false,这对流提取没有影响.
造成问题的原因是默认情况下,流只识别值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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,你的变化并没有使代码工作.它似乎只适用于您使用的单个测试用例.通过更改,该函数无法从流中读取并返回未初始化的值.由于任何非零值都将被解释为true,因此该函数似乎可以正常工作,但是一旦您尝试提取"false",您将看到它失败(该函数仍然返回true).
编辑:修改代码以处理数字和alpha bool.