关于C++中std::string类型到模板T类型的转换

On the conversion from std::string type to template T type in C++

我在这个论坛上发现了用户 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)};
}

我的想法是在 getline_as 中创建一个 do-while 循环,但我无法让它工作。

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(...) 可以,但我会完全重新创建流。

您还应该使用 read-only 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;
    }
}