Reputation: 368
There is a template class in c++:
#include <iostream>
#include <vector>
using std::ostream;
using std::vector;
template<typename T>
class Business {
public:
// default constructor
Business() {
customers.push_back(0);
}
// value constructor
Business(vector<T> vec) {
for (int i = 0; i < vec.size(); ++i)
customers.push_back(vec[i]);
}
T getInfo(int i) const {
if (i < 0 ) return 0;
else return customers[i];
}
friend ostream &operator<<(ostream &os, const Business<T> &b) {
std::string message = "";
for (int i=0 ; i<b.customers.size() ; ++i) {
message += b.getInfo(i) + " ";
}
return os << message;
}
private:
vector<T> customers;
};
But I receive the following error about the operator<<
body:
error: invalid operands to binary expression: message += b.getInfo(i) + " ";
After receiving that error, I changed the errorprone line of code to:
message += b.getInfo(i)
But then the error was:
error: no viable overloaded '+=': message += b.getInfo(i)
Edit: There is a main class in which I have:
Business<Merchant<95>> bu({45, 87, 95, 23});
std::cout << bu << endl;
where Merchant<95>
is a another template class.
The error I receive is follows by:
in instantiation of member function 'operator<<' requested here: cout << bu << endl;
I wonder how to fix it?
Thanks.
Upvotes: 1
Views: 94
Reputation: 368
Thank you all people who spent time to solve the question, I just needed to change the body of the for loop
inside friend ostream &operator<<
. Therefore, the correct way is as follows:
friend ostream &operator<<(ostream &os, const Business<T> &b) {
for (int i=0 ; i<b.customers.size() ; ++i) {
os << b.getInfo(i);
}
return os;
}
Upvotes: 2
Reputation: 125
The error you are receiving is related to the type (class) that you are instantiating the template on -- Merchant in your main example --, not the template class Bussiness itself.
Make sure that you have defined a function within Merchant to convert it to a string, or even char const*, and your code will compile.
Upvotes: 1
Reputation: 792
I could not provide a fix without looking at your Merchant
class template. I can tell what the issue is,
When you instantiate a Business
with Merchant
, the T
in your class template is replaced with a Merchant
. The compiler stamps out a Business<Merchant>
that will have a member function like the following, among other things,
Merchant getInfo(int i) const {
if (i < 0 ) return 0;
else return customers[i];
}
As you can see, getInfo
returns a Merchent
(the returned T
is replaced with Merchent
).
Now this is where the problem creeps in. Consider the following now,
std::string message = "";
for (int i=0 ; i<b.customers.size() ; ++i) {
message += b.getInfo(i) + " ";
}
In message += b.getInfo(i);
, message
is of type string
and b.getInfo(i)
returns a Merchant
as we saw before. The compiler doesn't know how to convert a Merchant
to string
to add it to message
. Thus is throws a no match for 'operator+='
.
A fix would to be tell the compiler how to convert a Merchant
to a string explicit. This requires defining operator std::string()
in Merchant
.
It might look like so,
Merchant<T>{
...
public:
operator std::string() const {
return to_string(MerchantID)+... }
...
};
This depends on your Merchant
and the primitive types that is has within. See operator std::string() const?.
Upvotes: 1