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

How do I std::getline into a template type?

本文关键字:类型 getline std 转换      更新时间:2023-10-16
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"。我怎样才能让它将 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';
}

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

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

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

这是一个演示。

除了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>();
}