我如何将std :: getline转换为模板类型?

问题描述 投票:1回答:2
template <typename T>
T getUserInput(std::string prompt = "")
{
    T input;
    std::cout << prompt;
    if (std::is_same<T, std::string>::value)
    {
        std::getline(std::cin, input);
    }
    else
    {
        std::cin >> input;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    return input;
}

当类型为字符串时(为了包含空格),我试图使用getline而不是cin,但是我收到一堆错误消息,说我没有为std :: getline提供足够的参数。我也尝试这样做:

    if (std::is_same<T, std::string>::value)
    {
        std::string sInput = "";
        std::getline(std::cin, sInput);
        return sInput;
    }

但是我收到一个错误消息,说我不能从'std :: string'转换为'T'。我如何才能将其视为std :: string?

编辑:这是我的称呼方式:

int main()
{
    int x = getUserInput<int>("Please type a number: ");
    std::cout << x << '\n';
    std::string test = getUserInput<std::string>("Please type a string: ");
    std::cout << test << '\n';
}
c++ templates c++17 stdstring
2个回答
2
投票

[当您用T以外的某些std::string调用函数时,getline代码将不会编译,因为无论是否采用分支,都需要编译所有代码。

为了避免在不需要时使用getline编译分支,可以使用if constexpr,如下所示:

if constexpr (std::is_same_v<T, std::string>)
{
    std::getline(std::cin, input);
}
else
{
    std::cin >> input;
}

这里是demo


0
投票

if constexpr之外的另一个选项(没有问题)是函数重载和/或专业化,例如:

// default version if not specialized
template<typename T>
T doUserInput()
{
    T input;
    std::cin >> input;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return input;
}        

template<>
std::string doUserInput() 
{
    std::string s;
    std::getline(std::cin, s);
    return s;
}

template <typename T>
T getUserInput(std::string prompt = "")
{
    std::cout << prompt;
    return doUserInput<T>();
}
© www.soinside.com 2019 - 2024. All rights reserved.