num_get преобразование фасета и потока строки в логическое значение - не удается с инициализированным логическим значением? - PullRequest
2 голосов
/ 07 октября 2010

Я унаследовал шаблон для преобразования строки в числовое значение и хочу применить его для преобразования в логическое .Я не очень опытен с классами stringstream и 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_

Почему это работает?Я принимаю, что инициализация bool с '0' неверна, но почему это может привести к сбою преобразования SStream>>num?

Ответы [ 2 ]

7 голосов
/ 07 октября 2010

Инициализация bool с 0 надежно установит его в 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;  
}  

Обратите внимание, что ваше изменение не заставило код работать.Похоже, это было сделано для одного тестового примера, который вы использовали.С вашим изменением функция не смогла прочитать из потока и вернула неинициализированное значение.Поскольку любое ненулевое значение будет интерпретировано как истина, функция, кажется, работает, но как только вы попытаетесь извлечь "false", вы увидите, что она не работает (функция по-прежнему возвращает истину).

Редактировать: Адаптирован код для обработки как числовых, так и буквенных значений.

1 голос
/ 07 октября 2010

Это связано с тем, что преобразование потока строк из 'true' завершается неудачно - шаблон вашей функции должен проверить SStream.fail() перед его возвратом, чтобы вы могли легче обнаружить подобные сбои.

Когда вы запускаете bool, его значение равноложный.Когда вы не инициализируете его (после удаления = 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;  
} 
...