C++: multiple operator definitions in different namespaces - c++

I'm troubled by conflict between two definitions of operator<<.
Suppose that I've been a great fan of ACE library and been using ACE_Time_Value in my code. One day I noticed ACE 6.x was out and tried to migrate my code from ACE 5.x to 6.x. Then I got a problem: ACE 6.x newly introduced operator<<(std::ostream &, const ACE_Time_Value &) in the global namespace, but my code had implemented my own version of operator<< since 5.x era, and two operator<< conflicted. Unfortunately the output from the "official" operator<< is unsatisfactory and I need to keep using my own version. How can I pretend there's no "official" operator<< in the global namespace? Luckily(?) all my code is under my own namespace.
Conceptually my problem can be summarized as:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; }
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Banana" ; }
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
// cout << "The current time is " <<
// t << endl; // error: ambiguous overload for 'operator<<'
}
}
int main() {
mine::bar();
}
http://ideone.com/NJXIz9

You can do something like below and make use of inheritance:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; return os; }
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
struct New_ACE_Time_Value: ACE_Time_Value {};
ostream &operator<<(ostream &os, const New_ACE_Time_Value &) { os << "Banana" ;
return os;
}
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
New_ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " <<
t << endl; // error: ambiguous overload for 'operator<<'
}
}
Probably you should also make 'NewACE_Time_Value' non copyable to shrug off object slicing issues.

This is how I would solve your conceptual example:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
namespace ACE
{
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; return os; }
}
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Banana" ; return os; }
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " << t << endl;
}
}
int main() {
mine::bar();
}
Since ACE is open-source, it shouldn't be too hard to apply the same modifications so that their <<operator overload is wrapped inside a namespace.

First, you should add "return os;" in our operator overloading (<<).
Second, add Preprocessor directives to one of two << overloading like this:
#ifdef Oper
ostream &operator<<(ostream &os, const ACE_Time_Value &)
{
os << "Banana" ; return os;
}
#endif

I ended up in defining a wrapper object with operator<<.
namespace mine {
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
struct AceTimePrinter {
const ACE_Time_Value &tv;
AceTimePrinter(const ACE_Time_Value &tv) : tv(tv) { }
inline friend std::ostream &operator<<(
std::ostream &os, const AceTimePrinter &o) {
const ACE_Time_Value &tv = o.tv;
return os << "Durian" ;
}
};
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " <<
AceTimePrinter(t) << endl;
}
}
We chose not to use inheritance because we cannot change existing method signatures in the ACE reactor framework, such as virtual int handle_timeout (const ACE_Time_Value &current_time, const void *act=0)

Related

VS2015 compile error for template function with "endl" [duplicate]

This question already has answers here:
Why do stream operators return references in C++?
(3 answers)
Closed 6 years ago.
#include "stdafx.h"
#include <iostream>
using namespace std;
// move operation is not implicitly generated for a class where the user has explicitly declared a destructor
class A {
public:
friend inline void operator << (ostream &os, A& a) {
os << "done" << endl;
}
};
template <typename T>
void done(T a) {
cout << a;
}
template<typename T>
void g(T h) {
cout << h << endl;
}
int main()
{
A a;
done(a);
// g(a); // with error: "mismatch in formal parameter list" and '<<': unable to resolve function overload.
return 0;
}
As the comments, it is so weird that with 'endl', the code cannot be compiled
with error: "mismatch in formal parameter list" and '<<': unable to resolve function overload.
You should return a reference to the stream so that you can chain the function calls
friend inline std::ostream& operator << (std::ostream &os, A& a) {
os << "done" << endl;
return os;
}
Not this
friend inline void operator << (ostream &os, A& a) {
os << "done" << endl;
}
When you use
friend inline void operator << (ostream &os, A& a)
the line
cout << h << endl;
is a problem since there is no operator<< between void and endl.

Operator << overload inheritance, why I got input from base class, instead of child class?

I have a class, let's call it A, it has only one field, aa. I have another class, B, which inherits class A, and instead of having the aa field, it also has its own field, bb. Now, I overloaded operator << (cout) for both classes. I tried to use polimorphism, but it seems that polimorphism does not work properly with operators. My code shows me only aa field when using operator cout for showing the object obj.
I mean, do I always need to add the virtual word to overload the function from the base class in a child class? If so, how should I do the same with operators, operators can't be virtual ...
#include <iostream>
#include <ostream>
using namespace std;
class A
{
protected :
int aa;
public:
A(int aa) {this->aa = aa;}
~A(){}
friend ostream &operator<<(ostream &os, const A& obj);
virtual void show() {cout << "a = " << aa << "\n"; }
};
ostream &operator<<(ostream &os, const A& obj)
{
for(int i=0; i<80; i++)
os << "-";
os << "\n";
os << "a = " << obj.aa << "\n";
for(int i=0; i<80; i++)
os << "-";
os << "\n";
return os;
}
class B : public A
{
private :
int bb;
public:
B(int aa, int bb) : A(aa) {this->bb = bb;}
~B(){}
friend ostream &operator<<(ostream &os, const B& obj);
void show() {cout << "a = " << aa << "\n"; cout << "b = " << bb << "\n";}
};
ostream &operator<<(ostream &os, const B& obj)
{
for(int i=0; i<80; i++)
os << "-";
os << "\n";
os << "a = " << obj.aa << "\n";
os << "b = " << obj.bb << "\n";
for(int i=0; i<80; i++)
os << "-";
os << "\n";
return os;
}
int main()
{
A *obj = new B(2,3);
cout << *obj;
obj->show();
delete obj;
return 0;
}
I mean, do I always need to add the virtual word to overload the function from the base class in a child class? If so, how should I do the same with operators, operators can't be virtual ...
Sure they can. But only member functions can be virtual, and these operators are not members functions - they're global functions.
In this case, you can't make them member functions (because the first parameter isn't an instance of your class). But you could create a virtual member function and have the operator call it:
class A
{
protected:
virtual void print(ostream &);
public:
friend ostream &operator<<(ostream &os, const A& obj);
// ... other stuff ...
};
ostream &operator<<(ostream &os, const A& obj)
{
obj.print(os);
return os;
}
and then override print instead of operator<<.

Storing values in a container

I'm trying to read two values from a file and store them in my class called God. God has two data members, name and mythology. I wish to store the values in a list<God> (the god and its respective mythology) and then print them out. Here is my code so far:
#include <iostream>
#include <fstream>
#include <list>
#include <string>
using namespace std;
class God {
string name;
string mythology;
public:
God(string& a, string& b) {
name=a;
mythology =b;
}
friend ostream& operator<<( ostream& os,const God&);
};
void read_gods(list<God>& s) {
string gname, gmyth;
//reading values from file
ifstream inFile;
inFile.open("gods.txt");
while(!inFile.eof()) {
inFile >> gname >> gmyth ;
s.push_back(God(gname, gmyth));
}
}
ostream& operator<<( ostream& os,const God& god) {
return os << god.name << god.mythology;
}
int main() {
//container:
list<God> Godmyth;
read_gods(Godmyth);
cout << Godmyth;
return 0;
}
If for example I read in Zeus, Greek then how would I be able to access them?
The error I'm receiving is:
error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'|
You should write either operator << or some member function for class God that outputs its data members.
For example
class God
{
public:
std::ostream & out( std::ostream &os ) const
{
return os << name << ": " << mythology;
}
//...
};
Or
class God
{
public:
friend std::ostream & operator <<( std::ostream &, const God & );
//...
};
std::ostream & operator <<( std::ostream &os, const God &god )
{
return os << god.name << ": " << god.mythology;
}
In this case instead of invalid statement
cout << Godmyth << endl;
you could write
for ( const God &god : Godmyth ) std::cout << god << std::endl;
Or if you simply want to access the data members then you should write getters.
For example
class God
{
public:
std::string GetName() const { return name; }
std::string GetMythology() const { return mythology; }
//...
There is no overloaded operator<< allowing printing std::list's content using std::cout.
What you can do?
As #Vlad mentioned, you can write
for ( const God &god : Godmyth )
std::cout << god << '\n';
Alternatively, you can write your own operator<<:
template<typename T>
std::ostream& operator<< (std::ostream &os, const std::list<T> &_list){
os << "[\n";
for ( const auto &item : _list )
os << item << ";\n";
return os << ']';
}

Use print function for output of overloaded << operator?

I have successfully overloaded the '<<' operator which I believe is referred to as the insertion operator. I have a print function which prints the information of an instance of a card object, how can I call this print function when the operator is used
example:
Card aCard("Spades",8); //generates an 8 of spades card object
aCard.Print(); // prints the suit and value of card
cout << aCard << endl; // will print something successfully but how can I get the same results as if I were to call the print function?
In my implementation file card.cpp I have overloaded the << for use with my card class.
Card.cpp
void Card::Print()
{
std::cout << "Suit: "<< Suit << std::endl;
std::cout << "Value:" << Value << std::endl;
}
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
Print();//this causes an error in the program
}
Card.h
class Card
{
public:
std::string Suit;
int Value;
Card(){};
Card(std::string S, int V){Suit=S; Value=V};
void Print();
friend std::ostream& operator<<(std::ostream&, const Card&)
};
You do only want one implementation. You could either make a Print function that takes an ostream and performs all of the print logic then call it from Print() and operator<<
void Card::Print()
{
Print(std::cout);
}
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
Print(out);
}
void Card::Print(std::ostream &out)
{
out << "Suit: "<< Suit << std::endl;
out << "Value:" << Value << std::endl;
return out;
}
Or you could have the operator<< contain the print logic and call operator<< from Print:
void Card::Print()
{
std::cout << *this;
}
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
out << "Suit: "<< Suit << std::endl;
out << "Value:" << Value << std::endl;
return out;
}
You need aCard.Print() in operator<< not Print()
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
aCard.Print();
}
You don't say what the error is but basically you're calling a globally defined Print() function or a function that doesn't exist with your code as it stands.

How can I use cout << myclass

myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};