so I've got a project where I am inserting user entered data into classes. So I've overloaded the >>
operator. Because I have classes with similar structures, I made the overload a template to try to save time. Making this template overload a friend of the classes seems to work, as I get no compile errors.
My ClassDefs.h:
// ClassDefs.h
using namespace std;
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <tuple>
#include <map>
#include <typeinfo>
class measurement {
//friends
template<class measT> //measT are other similar measurement classes
friend istream & operator >> (istream&, measT&);
private:
string words;
public:
//constructors and things like that here
};
template<class measT>
istream& operator >> (istream& is, measT& meas) {
//a series of checks to ensure user entry is valid
//enter user entry into private data
//e.g.
string line;
getline(is,line);
meas.words = line;
return is;
}
The problem comes when using cin >> foo
in main
- I get a warning caption saying "more than one operator >> matches these operands". Accompanied by:
error C2593: 'operator >>' is ambiguous
This makes sense, but my crude understanding of overloads was that they allow you to use different types with that operator and the compiler "understands" which definition to use for each situation.
My main.cpp:
// main.cpp
#include "ClassDefs.h"
int main(){
string entry;
cin >> entry;
^^ error here
return 0;
}
I have looked around and seen things involving explicit, inline, namespace (my using namespace std;
seems dodgy) but I haven't seen anyone use this template overload arrangement and have this problem. I'm using Visual Studio 2015 Community.
Any help or advice would be greatly appreciated :)
So I solved this partially with the help of @user4581301 - I really needed to keep the >>
overload a template so that I could use that parameter for a template exception class inside it.
It has become a bit convoluted but I thought I'd share in case anyone else is having issues overloading operators with templates.
Firstly I changed measurement
from an abstract base class to a base class (so that it could be used as a template parameter) and changed the friend declaration inside to:
//ClassDefs.h
template <class measT>
friend istream& operator >> (istream&, measurement&);
Where measT
was the type of measurement involved, to be used as the parameter for the exception class.
Then later on in the header file, >>
was overloaded with the definition:
//ClassDefs.h
template<class measT>
istream& operator >> (istream& is, measurement& meas) {
//take user input
//do checks on it, throw Exception<measT> depending on which set of
exceptions are relevant
}
And most importantly I wasn't sure how to use an operator with a template parameter but it turns out you can do it explicitly:
//ClassDefs.h
template<class measT>
measT userNewMeas() { //function to take user input and make into a type
// of measurement
try { ::operator>><measT> (cin,newMeas); }
catch (Exception<measT>& error) {
cout << error << endl; // this output depends on which exception
// was called
}
And now I can use template userNewMeas()
in main.cpp
with template >>
and template Exception
. The goal is probably hard to see for everyone but I was trying to overload >>
for any measurement type, and have one Exception class containing different error messages to be thrown depending on which measurement was being entered.