Consider the useful code by Zaita posted at cplusplus.com , in particular the part which gets numbers safely, modified to be a function in my case:
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";
}
}
Now, my question is this: Can I remove the int
on the first line of the function definition for get_number(), and declare it at the top of my code with all the types I might want to return such as doing some declarations like this:
double get_number();
int get_number();
long get_number();
unsigned short get_number();
...
...
And somehow get it to do different returns depending on the variable I want to store the return from the function with? Currently I simply writing multiple definitions of essentially the same function while changing the name to get_someType
I am hoping I can do something like declare with this sort of syntax:
int get_number(int);
double get_double(double);
...
...
And my desire would be to do something like:
int x;
x = get_number(int);
I am sure this will NOT work however! Because it would be impossible to define the function's source code with parameters with no names...
Firstly, the get_number implementation you've found is badly written: what do you think happens when you get an EOF on input? It spins around printing "Please enter a valid number\\n" as fast as it can until you kill the program....
Secondly, you can't overload on return type - which means you can't have functions that only differ in the return type.
Finally, C++ has templates that can do what I think you want...
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";
}
You can then use if (get(my_int)) ...
or if (get(my_double))
etc..
As input can not be guaranteed to succeed, you really should either provide a boolean return type (as illustrated) or throw an exception once it's clear input can not succeed.
You're looking for function template
s !
This code is buggy (please don't use cplusplus.com as a reference), since it doesn't check that input from std::cin
is received.
A templated example would look something like this (untested):
#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;
}
}
To incorporate my comment below into this answer... In a class template or function template, typename
can be used as an alternative to class
to declare templated types. I prefer typename
because we're dealing with POD-types and not class
es.
This can be done with templates.
Here you can find out some template tutorials for beginners (start from 58..) http://thenewboston.org/list.php?cat=16
You can use templates, but as far as I know your function must have an argument of the type of that template as well, as in:
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";
}
}
The type of template ( T
) is resolved in compile time based on the type of argument passed to the function.
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" ;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.