I'm trying to overload the << operator for the nested class ArticleIterator.
// ...
class ArticleContainer {
public:
class ArticleIterator {
// ...
friend ostream& operator<<(ostream& out, const ArticleIterator& artit);
};
// ...
};
If I define operator<< like I usually do, I get a compiler error.
friend ostream& operator<<(ostream& out, const ArticleContainer::ArticleIterator& artit) {
The error is 'friend' used outside of class. How do I fix this?
You don't put the friend keyword when defining the function, only when declaring it.
struct A
{
struct B
{
friend std::ostream& operator<<(std::ostream& os, const B& b);
};
};
std::ostream& operator<<(std::ostream& os, const A::B& b)
{
return os << "b";
}
You must declare it as a friend inside the class, then define it outside the class without the friend keyword.
class ArticleContainer {
public:
class ArticleIterator {
// ...
friend ostream& operator<<(ostream& out, const ArticleIterator& artit);
};
};
// No 'friend' keyword
ostream& operator<<(ostream& out, const ArticleIterator& artit);
the friend keyword is used in the declaration to specify that this func/class is a friend. In the definition outside the class you may not use that keyword. Just remove it
Related
Compilation of this code fails:
class P {
//public:
class C {
friend std::ostream& operator<<(std::ostream &os, const C &c);
};
};
std::ostream& operator<<(std::ostream &os, const P::C &c) {
return os;
}
error:
test.cpp:12:53: error: 'C' is a private member of 'P'
std::ostream& operator<<(std::ostream &os, const P::C &c) {
^
test.cpp:6:9: note: implicitly declared private here
class C {
^
1 error generated.
Uncommenting public: makes this code to compile. And it obviously can be moved to the class itself.
But what is the correct way to define such operator<< in a cpp file for a private member class?
To see the private elements of P , your operator<< must be friend of P. So in order to be able to access the definition of class C:
class P {
class C {
...
};
friend std::ostream& operator<<(std::ostream &os, const C &c);
};
Then, your current operator will compile. But it can only access public members of C, since it is a friend of the enclosing P but not of the nested C:
std::ostream& operator<<(std::ostream &os, const P::C &c) {
return os;
}
If you also need to access private members of C you need to be double friend:
class P {
class C {
int x; //private
friend std::ostream& operator<<(std::ostream &os, const C &c); // to access private x
};
friend std::ostream& operator<<(std::ostream &os, const C &c); // to access private C
};
std::ostream& operator<<(std::ostream &os, const P::C &c) {
os<<c.x;
return os;
}
I tried to write an simple example for the <<-operator-overloading.
Before, i've never used the keyword "friend". But it does not work without it. What is the mistake i did or why do i need the friend keyword here?
class rational{
public:
rational(double num, double count)
: n(num),c(count){}
rational& operator+=(const rational& b){
this->n+= b.n;
this->c+= b.c;
return *this;
}
friend std::ostream& operator<<(std::ostream& os, const rational& obj)
{
std::cout << obj.n << "," << obj.c << std::endl;
return os;
}
private:
double n;
double c;
};
Thanks
You didn't make any mistake. The friend keyword gives your operator<<() implementation access to private (and protected, if you had any) members of your class.
Note that because it's a friend, operator<<() here is implicitly a free function and not a member function (if it were a member function, it could access private things already!). Because it's declared and defined only inside the class, it can only be found by argument-dependent lookup, but this is fine for operator<< and is a detail you don't have to worry about yet.
You want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming
class T {
public:
void stream_to(std::ostream& os) const {os << obj.data_;}
private:
int data_;
};
and call that from the operator:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.stream_to(os);
return os;
}
or make the operator a friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
so that it can access the class' private parts:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}
You are declaring and defining the operator inside the class, thus without friend it has an implicit first operand of type rational. You wouldn't have such problem if you had declared the operator outside the class, but then you wouldn't have access to n and c.
This is what I tried so far:
class Fahrzeug
{
public:
std::string Id() const;
void Id(const std::string &id);
friend std::ostream& operator<< (std::ostream &out, const Fahrzeug &fzg)
{
out << Id();
return out;
}
private:
struct DatenImpl;
boost::scoped_ptr<DatenImpl> _datenImpl;
};
This yields a compiler error:
error C2352: Id() - illegal call of non-static member function
How can I implement the ostream operator<< for a "pimpled" class?
Your definition should be:
friend std::ostream& operator<< (std::ostream &out, const Fahrzeug &fzg)
{
out << fzg.Id(); // <--- qualify call to Id()
return out;
}
The operator is not a class member, although defined inside the class.
How one can overload an operator<< for a nested private class like this one?
class outer {
private:
class nested {
friend ostream& operator<<(ostream& os, const nested& a);
};
// ...
};
When trying outside of outer class compiler complains about privacy:
error: ‘class outer::nested’ is private
You could make the operator<< a friend of outer as well. Or you
could implement it completely inline in nested, e.g.:
class Outer
{
class Inner
{
friend std::ostream&
operator<<( std::ostream& dest, Inner const& obj )
{
obj.print( dest );
return dest;
}
// ...
// don't forget to define print (which needn't be inline)
};
// ...
};
if you want the same thing in two different file (hh, cpp) you have to friend two time the function as follow:
hh:
// file.hh
class Outer
{
class Inner
{
friend std::ostream& operator<<( std::ostream& dest, Inner const& obj );
// ...
};
friend std::ostream& operator<<( std::ostream& dest, Outer::Inner const& obj );
// ...
};
cpp:
// file.cpp:
#include "file.hh"
std::ostream &operator<<( std::ostream& dest, Outer::Inner const& obj )
{
return dest;
}
I want to overload the operator << in one of my classes.
The signature goes like this:
friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
When I try to define it in the .cpp file it says that the operator<< exactly takes 1 argument, however, when I define it in the .h, it compiled/works fine.
This is how I define it in the .cpp file :
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... }
Does it have anything to do with friend functions needing to be defined in header files?
It can be defined in a cpp file, but it needs to at least be declared in a header file, otherwise all places where you want to use it will only see the stuff the stream itself gives you, not your overload.
// .h and in class
friend std::ostream& operator<<(std::ostream& os, MyClass const& v);
// .cpp
std::ostream& operator<<(std::ostream& os, MyClass const& v){
// print it
}
The problem is with the way you're defining it. It's not a member of the class, it's just a friend of the class. You need to drop the Annuaire:: prefix. So, change this:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ...
to this:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj){ // ...
The reason for the error message is that Annuaire::operator<<(std::ostream& os, const Annuaire& obj) would expect three arguments: the Annuaire instance that it's called on (as this), and and two additional arguments (os and obj).
As mentioned in David's answer, in this case the operator is not a member function, it is merely a friend function in the same namespace. This pointed me in the right direction in solving a very similar issue.
I'm posting this answer because it wasn't immediately obvious to me. Maybe because the implementation file where I was adding the operator wasn't fully enclosed in the namespace, and used a using-directive instead.
Shouldn't be relevant but I'm using VS2013.
//Foo.h
namespace Bar{
class Foo
{
public:
Foo();
private:
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
}
//Foo.cpp
using namespace Bar; //won't apply to the operator definition
Foo::Foo(){}// doesn't require the Bar qualifier because of the using-directive
//the operator required the Bar namespace qualifier
std::ostream & Bar::operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}
Friend functions, even if they seem to be declared inside the class are not member functions but rather namespace level functions (in the enclosing namespace). In your code you declare the friend function correctly, but you try to define it as a member function of the class:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){
That definition would be for a member function of Annuaire, called operator<<, that takes two arguments, which is invalid as operator<< can be overloaded in one of two ways: as a free function taking two arguments (left hand side and right hand side) or as a member function of the class that appears in the lhs of the expression taking an argument of the rhs type. In this particular case, since the lhs is std::ostream and you cannot modify it, you are left with the only option of using a free function:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
No such restriction; you're probably just writing it wrong. Should be something like this:
class Foo
{
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
std::ostream & operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}