Overloading a function using identical definitions in C++ - c++

I am aware of the process of function overloading in C++ through the use of differing parameters and definitions. However if I have two functions which are identical apart from their parameters is there a way to only have this definition once.
The functions I have used are to check for correct input (i.e. a number not a character is entered). One is for an int and the other a float. Because of this and the fact that I pass the variable by reference the definitions are exactly identical.
The two functions declarations are as follows:
void Input (float &Ref);
void Input (int &Ref);
And they then share the common definition of:
Function_Header
{
static int FirstRun = 0; // declare first run as 0 (false)
if (FirstRun++) // increment first run after checking for true, this causes this to be missed on first run only.
{ //After first run it is required to clear any previous inputs leftover (i.e. if user entered "10V"
// previously then the "V" would need to be cleared.
std::cin.clear(); // clear the error flags
std::cin.ignore(INT_MAX, '\n'); // discard the row
}
while (!(std::cin >> Ref)) // collect input and check it is a valid input (i.e. a number)
{ // if incorrect entry clear the input and request re-entry, loop untill correct user entry.
std::cin.clear(); // clear the error flags
std::cin.ignore(INT_MAX, '\n'); // discard the row
std::cout << "Invalid input! Try again:\t\t\t\t\t";
}
}
If there was a way around having to have two identical copies of the same code while it still being used for both parameter types then I could shorten the code of my programme significantly. I'm sure I'm not the only person with this issue but all my searches are returning are explanations of how to overload functions using multiple definitions.
Any help or advice would be much appreciated.

The best (and only ?) solution is to use template

Templates are useful:
template <typename T>
void Input (T &Ref)
{
...
}
std::string s;
int i;
float f;
Input(s);
Input(i);
Input(f);

template<class T>
void Input(T& ref)
{
..
}

Related

Input Combining with Previous Input Acts Correctly

In my class, I want the family data member to be one of the five strings in the static array fiveNewYorkFamilies[5]. I made a constructor to take input from the user and see if it corresponds to one of the elements in the array. If it does match, then I go on with my program; if not, I repeat the step using a goto. My program works fine, but there's one thing I don't understand: When I first insert the input, the variable family is empty as indicated by the empty function I put atop of it. However, if I fail to insert a correct input the first time, and continue to insert an input a second time, I am inserting an input atop the previous input. For example, if I input "Lebron" the first time and then insert "Corleone" the second time (the empty function reassures me that family is not empty), the variable family would be "LebronCorleone." In spite of this, my program works just fine. Can someone explain to me why is that? And if I'm misunderstanding the situation, can someone clear it up? Thank you.
class Godfather
{
std::string family;
public:
explicit Godfather(std::istream & is);
Godfather(): family("Corleone") {}
static std::string fiveNewYorkFamilies[5];
std::string getFamily() const {return this->family;}
};
std::string Godfather::fiveNewYorkFamilies[5] = {"Corleone", "Barzini", "Cuneo", "Stracci", "Tattaglia"};
Godfather::Godfather(std::istream & is)
{
label:
std::cout << family.empty();
is >> family;
bool match = false;
for(std::string * ptr = fiveNewYorkFamilies; ptr != fiveNewYorkFamilies + 5; ++ptr)
if(*ptr == family)
match = true;
if(!match)
goto label;
}
int main()
{
Godfather vito(std::cin);
}
You can improve the code by removing the goto label. Instead, use a while loop. When an input is correct, just return so the function ends.
Also, use a foreach loop when you parse the possible names. This way you won't care if the size of the possible names is changing (hence you won't need to change from 5 to 6, 6 to 7 etc. whenever you add a new possible name in the array).
Godfather::Godfather(std::istream& is) {
while (is >> family) {
for (const auto& possibleName : fiveNewYorkFamilies) {
if (family == possibleName)
return;
}
}
}
P.S. Good luck with your Sa:Mp server.

How to use template to make variables generalized in c++?

I'm trying to take input from the user and the user have multiple choice to enter the different types of inputs(char, int float). And according to the value entered I have to take proper action.
eg. I have a function below :-
int* function(int data)
{
int a[50];
int k = 0;
a[k] = data;
k++;
// I want to make choice generalized so that it can accept both type of
// values int as well as char.
cout<<"\n Enter integer element to insert into array, otherwise press 'n' to terminate array list: ";
cin>>choice;
if(choice != 'n')
function(choice);
return a;
}
So, in the above example I want to make choice generalized. I how to use template for function and classes but, I want to do this for variable. Please help.
NOTE: the above code is just a example to illustrate my problem.
Thank's.
Templates are a compile time construct, so there is no way to let the user input have an influence on the template type.
What you can do is some template based automation of the input conversion where you decide which template instantiations should be checked. Suppose you have a class to handle your input conversion called GenericInput with template functions bool GenericInput::CanConvert<TargetType>() and TargetType GenericInput::Convert<TargetType>()
GenericInput in;
std::cin >> in;
if (in.CanConvert<int>()) {
// some action
}
else if (in.CanConvert<char>()) {
// another action
}
// ...
It would basically be a wrapper for the idea to first read the string and then check, how the string can be interpreted.
To implement it, you would need the following things:
Overload operator >>
std::istream& operator >>(std::istream& stream, GenericInput& element) {
/* TODO: read input into string member of GenericInput object */
return stream;
}
The GenericInput class
class GenericInput {
private:
std::string _inputElement; // store input as base for conversion
public:
// TODO: standard class implementation
template <typename TargetType>
bool CanConvert() {
// TODO: create std::stringstream from _inputElement and try to read into a TargetType variable
// return true if the stringstream is valid after the read
}
template <typename TargetType>
TargetType Convert() {
// TODO: create std::stringstream from _inputElement and try to read into a TargetType variable
// return variable if the stringstream is valid after the read, otherwise report error
}
}
Regarding the "valid" stringstream after read, it might be important to check two things: if the stringstream is in some kind of error state, conversion failed. If there are unread characters in the stringstream, the conversion was incomplete, which may also count as a failure.
Please don't expect this to be working out of the box, its more of an idea scratch than an actual implementation.

Simultaneous use of overloading of parameter and overloading of return type

I was trying to make a program, which automatically detects the data type of input given by user.
My approach :
int input(istream& i)
{
int k;
i>>k;
return k;
}
float input(istream& i)
{
float k;
i>>k;
return k;
}
void showval(int h){cout<<h;}
void showval(float h){cout<<h;}
int main()
{
showval(input(cin));
return 0;
}
As you can see, I used overloading of parameters and overloading of return type of two different functions, but at the same time. However, the program gives error as
"new declaration float input(istream& i) disambiguates the old
declaration int input(istream& i)”.
I don’t understand, how this creates ambiguity. Is it because, the two different functions (showval and input) are dependent?
Also after going through few articles on overloading, what i realised is that in C++, methods can be overloaded only if they differ by parameters.
However this link has a trick by which he was able to overload functions by return type. Is it possible to use the same trick in my program? Also, is there any way by which i can tell the compiler that the function input has parameter which is user dependent, and its data type may or may not differ. Does C++ forbid such possibilty?
Let's say that types such as int and float are specific, and types such as the proxy object shown in the linked question are generic. Our options are to be specific to begin with, in which case we just coast through the rest, or we give rise to a generic type and handle all the various specific types we may support.
The proxy object shown in the linked question is an example of a variant type, and boost::variant is a generic implementation of this. For example, boost::variant<int, float> allows us to hold either int or float.
My recommendation really depends what you want. Do you
want to specify the type you expect to get from the user and throw on unexpectd input? (specific to begin with and coast) OR,
want to give rise to a different type depending on what the user inputted and specify a set of types you can handle? (Give rise to a generic type and handle the various specific types)
Specifying the type you expect from the user
In this case we can simply make the function templated and we specify the type we expect through the template parameter.
The example shown is kept totally generic but you can restrain template parameters using various techniques. Check out my answer regarding this topic.
#include <iostream>
/* Read data of type T from an input stream. */
template <typename T>
T read(std::istream &strm) {
T val;
strm >> val;
if (!strm) {
throw /* something */;
} // if
return val;
}
/* Print data of type T. */
template <typename T>
void print(const T &val) {
std::cout << val;
}
int main() {
print(read<int>(std::cin));
}
This will give rise to an int for input such as 1 and even for input such as 1., 1.0 and 1.2.
Handling different types you may get from the user
In this case we're actually lexing the input stream from the user. Our read function will give rise to a generic type, boost::variant<int, float>.
#include <iostream>
#include <boost/variant.hpp>
/* Naive implementation of a lexer. */
boost::variant<int, float> read(std::istream &strm) {
std::string lexeme;
strm >> lexeme;
try {
std::size_t idx;
auto val = std::stoi(lexeme, &idx);
if (idx == lexeme.size()) { // Make sure we converted the entire lexeme.
return val;
} // if
} catch (const std::exception &) {
// Do nothing. We'll try to lex it as float instead.
} // try
std::size_t idx;
auto val = std::stof(lexeme, &idx);
if (idx == lexeme.size()) { // Make sure we converted the entire lexeme.
return val;
} // if
throw /* something */;
}
/* Print the type and the value, to check that we have the correct type. */
void print(const boost::variant<int, float> &val) {
class visitor : public boost::static_visitor<void> {
public:
void operator()(int that) const {
std::cout << "int: " << that << std::endl;
}
void operator()(float that) const {
std::cout << "float: " << that << std::endl;
}
}; // visitor
boost::apply_visitor(visitor(), val);
}
int main() {
print(read(std::cin));
}
This approach will give rise to int for input such as 1, and give rise to float for input such as 1., 1.0 as 1.2.
As you can see, we give rise to a generic type, boost::variant<int, float>, and handle the various specific types, int and float, in the visitor.
The problem is that the compiler cannot possibly know which version of input to call. It is only within input that you actually attempt to extract from the stream, and only at that point can you know what the user has inputted. And even then, there's no reason the user can't enter 1.5 and then you extract into an int, or they enter 5 and you extract into a float.
Types are compile-time constructs. The compiler uses the type information to produce the program executable, so it must know what types are being used at compile time (way before the user inputs anything).
So no, you can't do this quite like this. You could extract a line from the input, parse it to determine whether it's a floating point value or an integer (does it have a .?), and then have a separate execution path for each case. However, instead I recommend deciding what the input that you expect from the user is (an int or a float?) and just extract that.
And also no, the trick with the proxy won't work for you. Firstly, as I mentioned, the format of the input is not known at compile time anyway. But secondly, in that code, the type that was required was known by the type of the variable being declared. In one line they did int v = ... and in the other they did double u = .... In your case, you're passing the result to showval which could take either an int or double and the compiler has no idea which.

Error LNK2019 C++ Unbearably simple program

I was writing a program to search fro a range of prime numbers, and about halfway through to check my progress I decided to build it to make sure everything is working okay, I keep getting error LNK2019! It says it is an unresolved external.I did some research but I don't understand much of anything. Here is the code.
#include <iostream>
using namespace std;
int singlePrime(int subjectNumber);
int main() {
cout<<"Would you like to find a single prime number(1), or a range(2)?"<<endl;
int methodchoice;
cin>>methodchoice;
if(methodchoice ==1) {
int subjectNumber;
cout<<"Which number would you like to test for primeness?"<<endl;
cin>>subjectNumber;
int singlePrime(subjectNumber);
}
if(methodchoice==2) {
int lowRange;
int highRange;
cout<<"Input the low value for your range."<<endl;
cin>> lowRange;
cout<<"Input the high value for your range"<<endl;
cin>> highRange;
for (int index=lowRange; index<highRange;index++) {
if (index=highRange) {
break;
}
singlePrime(index);
}
}
}
Here you declare a function that you never define:
int singlePrime(int subjectNumber);
The linker complains because you invoke this function, but its body is found nowhere.
To verify that this is the problem, replace the declaration with a definition containing some dummy implementation:
int singlePrime(int subjectNumber)
{
return 0;
}
Also notice, that you have a useless initialization of an integer called singlePrime here:
if (methodchoice ==1) {
int subjectNumber;
cout<<"Which number would you like to test for primeness?"<<endl;
cin>>subjectNumber;
int singlePrime(subjectNumber);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Why this?
}
You probably meant this line to do something else (most likely invoke the singlePrime() function), since singlePrime won't be visible outside that block's scope.
It's probably flagging this function prototype:
int singlePrime(int subjectNumber);
You haven't defined a body for the function. You need to implement it (or at least give it a dummy implementation).
Well, my psychic debugging skills have pinpointed the problem. The following code:
int singlePrime(int subjectNumber);
tells the compiler that there exists a function called singlePrime which takes an int and returns an int.
Of course, you then never provide the code for that function... The compiler assumes it's in some other .cpp file and says "oh, well, the linker will take care of that."
And when the linker comes along, it sees that it's supposed to find a function called singlePrime which accepts an int and returns an int. But that function is nowhere to be found.
Simple fix, change:
int singlePrime(int subjectNumber);
into
int singlePrime(int subjectNumber)
{
// some code here to do whatever singlePrime is supposed to do
// be sure to return the correct number. For now, return the
// number of the beast!
return 666;
}
Further down in your code, you seem to try to call this function:
if (methodchoice ==1) {
int subjectNumber;
cout<<"Which number would you like to test for primeness?"<<endl;
cin>>subjectNumber;
int singlePrime(subjectNumber); // What?
}
But this isn't how you call functions in C or C++. You should take a closer look at your book or class notes. You would do something like this:
// call singlePrime and store the result in a variable called
// ret so that we can use it.
int ret = singlePrime(subjectNumber);
And for future reference, it would help if you posted the complete error message you get. You know, in case our crystal balls are malfunctioning because of solar flares.

Functions That Will Only Accept Certain Argument Values (C++)

Let me set the scene..
You can open files in a specific mode like this:
#include <fstream>
int main(){
std::fstream myfile;
myfile.open ("filename", std::ios::app);
return 0;
}
that second parameter is an enumerated type-
which is why you will get a compiler error attempting this:
#include <fstream>
int main(){
std::fstream myfile;
myfile.open ("filename", std::ios::lksdjflskdjflksff);
return 0;
}
In this example, the class doesn't have to account for the second parameter being incorrect, and the programmer never has to worry about passing in a nonsensical value.
Question: Is there a way to write functions that must take a particular type AND a particular value?
Let's say I wanted to re-implement a File Handling class similar to the one above.
The difference is I'm making the second parameter a char instead of an enumerated type.
How could I get something like this to work:
#include "MyFileHandler.h"
int main(){
MyFileHandler myfile1;
myfile.open ("filename", 'a'); //GOOD: a stands for append
myfile.open ("filename", 't'); //GOOD: t stands for truncate
myfile.open ("filename", 'x'); //COMPILER ERROR: openmode can not be the value 'x'
return 0;
}
Going beyond this, can I get the compiler to test the validity of argument values through functional means?
Example:
void IOnlyAcceptPrimeNumbers(const int & primeNumber);
int function(void);
int main(){
IOnlyAcceptPrimeNumbers(3); //GOOD: 3 is prime
IOnlyAcceptPrimeNumbers(7); //GOOD: 7 is prime
IOnlyAcceptPrimeNumbers(10); //COMPILER ERROR: 10 is not prime
IOnlyAcceptPrimeNumbers(10+1); //GOOD: 11 is prime
IOnlyAcceptPrimeNumbers(1+1+1+1); //COMPILER ERROR: 4 is not prime
IOnlyAcceptPrimeNumbers(function()); //GOOD: can this somehow be done?
return 0;
}
void IOnlyAcceptPrimeNumbers(const int & primeNumber){return;}
int function(void){return 7;}
I believe i've made it clear what I want to do and why I find it important.
Any solutions out there?
If you want compile-time checked values, you could write templates rather than function arguments:
template <char> void foo(std::string const &); // no implementation
template <> void foo<'a'>(std::string const & s) { /* ... */ }
template <> void foo<'b'>(std::string const & s) { /* ... */ }
Usage:
foo<'a'>("hello world"); // OK
foo<'z'>("dlrow olleh"); // Linker error, `foo<'z'>` not defined.
If you want an actual compiler error rather than just a linker error, you could add a static_assert(false) into the primary template.
No, if you specify that your function will take a char, it will take any char.
The "resolution" used by the compiler for checking passed arguments is the type rather than a set of possible values.
In other words, you need to use enumerations for this, or move the checking to runtime, or do something horrid like:
static void processAorT (char typ, char *fileName) { ... }
void processA (char *fileName) { processAorT ('a', fileName); }
void processT (char *fileName) { processAorT ('t', fileName); |
(not something I would advise, by the way).
Having said that, I'm not sure what you're proposing is a good idea anyway.
The compiler may be able to detect invalid constants, but won't be very successful if the parameter passed into IOnlyAcceptPrimeNumbers has come from a variable or, worse, input by a user.
The API is a contract between caller and function and, if the rules of that contract are not followed, you're free to do whatever you want, though hopefully you'd document it.
In other words, that function should begin:
void IOnlyAcceptPrimeNumbers (int num) {
if (!isPrime (num)) return;
// do something with a prime number.
}
(or the equivalent for your function that accepts a and t but not x). Doing nothing when passed invalid parameters is a reasonable strategy, as is returning an error or throwing an exception (though no doubt some would argue with this).
How you handle it is up to you, but it needs to be handled at runtime simply because the compiler doesn't have all the information.
You can only check value validity at runtime. Best you can do is use assert to stop programm execution if precondition is violated.
No. If you want to restrict the accepted arguments you need to use enums or accept an object that inherits from a specific interface (depends how sophisticated you want to make it). Enums is the common way to address this issue.
The example about the IOnlyAcceptPrimeNumbers is not well designed. If you want to achieve something similar it would be better to provide a class method that is something such as bool setNumber(int number) that will return false if the number is not prime. If you want to do it in the costructor the real alternative is to throw an exception (that is not really nice to do).
The concept is that you can not simply rely that the user will pass you only elements from a (correct) subset of the values that the parameter type allows.
While more restrictive than your requirements (this limits the values a particular type can hold), you can always try something like:
// Vowel.h
#ifndef VOWEL_H_
#define VOWEL_H_
class Vowel
{
public:
static const Vowel A;
static const Vowel E;
static const Vowel I;
static const Vowel O;
static const Vowel U;
char get() const { return value; }
private:
explicit Vowel(char c);
char value;
};
#endif /* VOWEL_H_ */
// Vowel.cpp
#include "Vowel.h"
Vowel::Vowel(char c) : value(c) {}
const Vowel Vowel::A('A');
const Vowel Vowel::E('E');
const Vowel Vowel::I('I');
const Vowel Vowel::O('O');
const Vowel Vowel::U('U');
Since the char constructor is private, only Vowel itself can construct objects from chars. All other uses are done by copy construction or copy assignment.
(I think I originally learned this technique from Scott Meyers; thank him / blame me.)