![](/img/trans.png)
[英]How do I make my function return different results depending on type it's been called using templates in C++
[英]Is it possible, in C++, to do some funky stuff when calling my function to return different types depending on my program's needs?
考虑一下Zaita发布在cplusplus.com上的有用代码,特别是安全获取数字的部分,在我的情况下修改为函数:
int get_number()
{
/**
* cplusplus.com/forum/articles/6046
* gets number from input stream
**/
string input = "";
int number = 0;
while (true)
{
getline(cin, input);
stringstream checks(input);
if (checks >> number)
return number;
cout << "Please enter a valid number\n";
}
}
现在,我的问题是这样的:我可以在get_number()的函数定义的第一行中删除int
,并在我的代码顶部用所有可能要返回的类型声明它,例如进行如下声明: :
double get_number();
int get_number();
long get_number();
unsigned short get_number();
...
...
并以某种方式让它根据要存储函数返回值的变量执行不同的返回值? 目前,我只是在将名称更改为get_someType
同时编写基本相同功能的多个定义。
我希望我可以用这种语法做类似声明的事情:
int get_number(int);
double get_double(double);
...
...
我的愿望是做类似的事情:
int x;
x = get_number(int);
我确信这将无法正常工作! 因为用没有名字的参数来定义函数的源代码是不可能的...
首先,您发现的get_number实现写得不好:输入时出现EOF,您会怎么想? 它会尽可能快地打印“请输入有效的数字\\ n”,直到您终止程序为止。
其次,您不能在返回类型上重载-这意味着您不能拥有仅在返回类型上有所不同的函数。
最后,C ++的模板可以完成我认为您想要的...
template <typename T>
bool get(T& x)
{
std::string input;
if (!getline(std::cin, input))
return false;
stringstream checks(input);
if (checks >> x)
return true;
cout << "Please enter a valid value\n";
}
然后可以使用if (get(my_int)) ...
或if (get(my_double))
等。
由于不能保证输入会成功,因此您真的应该提供布尔返回类型(如图所示),或者在输入明确无法成功后抛出异常。
您正在寻找功能template
s !
此代码有错误(请不要使用cplusplus.com作为参考),因为它不会检查是否接收到来自std::cin
输入。
模板化的示例如下所示(未经测试):
#include <string>
#include <sstream>
#include <iostream>
#include <stdexcept>
template <typename T>
T get_number()
{
std::string input = "";
T number; // Don't initialise to zero
bool done = false;
while (!done)
{
if (std::getline(std::cin, input)) // check for success
{
std::istringstream checks(input);
if (checks >> number)
{
done = true;
}
else
{
std::cout << "Please enter a valid number\n";
}
}
else
{
throw std::runtime_error("No input was received\n");
}
}
return number;
}
int main()
{
try
{
int i = get_number<int>();
float f = get_number<float>();
double d = get_number<double>();
char b = get_number<char>();
}
catch (const std::runtime_error& e)
{
std::cerr << e.what() << std::endl;
}
}
要将我在下面的评论合并到此答案中,请执行以下操作:在类模板或函数模板中,可以使用typename
代替class
来声明模板化类型。 我更喜欢typename
因为我们要处理POD类型而不是class
es。
可以使用模板来完成。
在这里,您可以找到一些适合初学者的模板教程(从58开始。) http://thenewboston.org/list.php?cat=16
您可以使用模板,但据我所知,您的函数也必须具有该模板类型的参数,例如:
template <class T>
T get_number(T arg)
{
/**
* cplusplus.com/forum/articles/6046
* gets number from input stream
**/
string input = "";
T number = 0;
while (true)
{
getline(cin, input);
stringstream checks(input);
if (checks >> number)
return number;
cout << "Please enter a valid number\n";
}
}
模板( T
)的类型在编译时根据传递给函数的参数的类型进行解析。
template<class T>
T get_number()
{
/**
* cplusplus.com/forum/articles/6046
* gets number from input stream
**/
string input = "";
T genericobj;
while (true)
{
getline(cin, input);
stringstream checks(input);
if (checks >> genericobj)
return genericobj;
cout << "Please enter a valid input\n" ;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.