(/ edit: добавлен 3-й выпуск)
Чтобы легко анализировать примитивные типы из различных источников (а также, возможно, некоторые объекты, перегружающие операторы << & >>), я создал эту функцию-шаблон:
#include <sstream>
#include <iostream> //only for the debug trace
#include <typeinfo> //only for the debug trace
template<typename T>
static inline bool getValue(std::string value, T& result)
{
//std::cout << "getValue : '" << value << "'" << std::endl;
//std::cout << "type : " << typeid(T).name() << std::endl;
std::stringstream ss(value);
ss >> std::boolalpha >> result;
//std::cout << "result : " << result << std::endl;
//std::cout << "ss.rdstate() : " << ss.rdstate() << std::endl;
return ss.good();
}
Эта шаблонная функция принимает строку и пытается извлечь значение в соответствии с заданным ссылочным типом.
Выход:
Для логического значения со значением "true":
getValue : 'true'
type : b
result : 1
ss.rdstate() : 0
Для логического значения со значением "1":
getValue : '1'
type : b
result : 0
ss.rdstate() : 4
Для целых:
getValue : '60'
type : i
result : 60
ss.rdstate() : 2
Для строки со значением "бла": (да, я знаю, бесполезно для строки, но если я хочу выполнить цикл по нескольким параметрам с различными типами ...)
getValue : 'blah'
type : Ss
result : blah
ss.rdstate() : 2
У меня здесь 2 вопроса:
1) логические значения
Чтобы иметь возможность читать строки значений "true" или "false", мне пришлось добавить этот манипулятор "std :: boolalpha". Но тогда я не могу успешно разобрать '0' или '1' для типа bool.
2) Флаг штата
В случае ошибки при разборе (например, с логической проблемой), rdstate возвращает 4 (то есть «ошибка»).
В случае, если это правильно, он либо вернет 0 (хорошо) для логического значения; или '2' (т.е. "eof") для целых чисел или строки.
Может кто-нибудь объяснить, почему такая разница между этими типами? Должен ли я считать "Eof" как правильно? Я предполагаю, что да.
Документация оператора >> (http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/) гласит, что failbit установлен для:
«Либо никакие символы не были извлечены, либо извлеченные символы не могут быть интерпретированы как допустимое значение соответствующего типа»
Таким образом, пустая строка вызовет сбой. (проверено, и rdstate равен 6, т.е. eof | fail);
3) дополнительный вопрос: значение в случае ошибки:
Тестируя, я пытался установить ошибку при установке int. Я вызвал мою функцию с инициализированным нулем int и пустой строкой:
int timeout=0;
getValue ("", timeout);
getValue : ''
type : i
result : 60000
ss.rdstate() : 6
Это значение в 60 000 выглядит для меня очень странно. это соответствует значению init другого int .. WTF!
Конечно, я проверяю результат, но некоторые другие пользователи не могут. Должен ли я включить исключения на failbit?