Я нашел на этом форуме следующий фрагмент, написанный пользователем Ben Voigt:
//forward declaration
template<typename T>
T getline_as(std::istream& s);
template<>
std::string getline_as<std::string>(std::istream& s)
{
std::string str;
std::getline(s,str);
return str;
}
template<typename T>
T getline_as(std::istream& s)
{
std::stringstream convert(getline_as<std::string>(s));
T value;
convert >> value;
return value;
}
Я ищу способ справиться с возможными сбоями convert >> value;. Моя цель была бы
чтобы повторить запрос пользователю, чтобы он правильно вставил данный ввод:
int main()
{
std::cout << "Please enter a number: ";
double number{getline_as<double>(std::cin)};
}
Моя идея состояла в том, чтобы создать цикл do-while внутри getline_as, но я не могу заставить его работать.
template<typename T>
T getline_as(std::istream& s)
{
std::stringstream convert;
T value;
do
{
convert(getline_as<std::string>(s));
}
while(!(convert >> value));
return value;
}





std::stringstream convert(...); — это вызов конструктора, но попытка сделать convert(...);после поток создан недопустима (требуется перегрузка потока operator(), чего он не делает). convert = std::stringstream(...) будет работать, но я бы просто полностью воссоздал поток.
Вы также должны использовать std::istringstream только для чтения, так как вы никогда ничего не записываете в него.
Я также сделал некоторые косметические изменения и в итоге получил следующее:
template <typename T>
[[nodiscard]] T getline_as(std::istream &s);
template <>
[[nodiscard]] std::string getline_as<std::string>(std::istream &s)
{
std::string str;
std::getline(s, str);
return str;
}
template <typename T>
[[nodiscard]] T getline_as(std::istream &s)
{
while (true)
{
T value{};
std::istringstream convert(getline_as<std::string>(s));
if (convert >> value)
return value;
}
}