2

文字列を数値に変換するためのテンプレートを継承し、それをブール値に変換するために適用したいと思います。私はstringstreamクラスとlocaleクラスの経験があまりありません。私は奇妙な振る舞いをしているようですが、誰かが私にそれを説明してもらえないかと思います。

template<typename 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」でブール値を初期化するのは間違っていることを認めますが、なぜこれによりSStream>>num変換が失敗するのでしょうか。

4

2 に答える 2

7

boolを0で初期化すると、確実にfalseに設定され、これはストリーム抽出に影響を与えません。

問題の原因は、ストリームがデフォルトで値のみを認識し、ブール値を処理する場合です01名前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を返します)。

編集:数値とアルファの両方のブールを処理するようにコードを調整しました。

于 2010-10-07T11:30:51.750 に答える
1

これは、「true」からの文字列ストリームの変換が失敗するためです。関数テンプレートはSStream.fail()、戻る前にチェックする必要があるため、同様の失敗をより簡単に発見できます。

boolを初期化すると、その値はfalseになります。初期化しない場合(= 0を削除した後)、ランダムなガベージ(通常はゼロ以外)であり、trueを返します。

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

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

if (SStream.fail())
{
    // conversion failure - handle error
    bool error = true;
}

return num;  
} 
于 2010-10-07T11:36:06.760 に答える