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';
}
[当您用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。
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>();
}