Why no static member operator() functions?

U

Urs Thuermann

I tried overloading the operator<<() for ostream as a static member
function in a class, but the compiler (gcc) complained that it should
be non-static or non-member. Why is this not possible? Since I want
to pass a private type of the class as argument, this is a problem.

What I tried to do is something like this:

#include <iostream>

using namespace std;

class Foo {
public:
void foo() {
#if 0
cout << "yadda yadda " << b << endl;
#endif
}
private:
struct Bar {
public:
#if 1
static ostream &operator<<(ostream &os, const Bar &b)
{
b.print(os);
return os;
}
#endif
private:
int bar;
void print(ostream &os) const { os << bar; }
};

Bar b;
};

I cannot make the operator<< a non-member function since its parameter
type Bar is private and I'd prefer to leave it so. How should I solve
this?

When I replace the "operator<<" by some other function name the code
compiles but I still cannot use << like in foo().

urs
 
V

Victor Bazarov

I tried overloading the operator<<() for ostream as a static member
function in a class, but the compiler (gcc) complained that it should
be non-static or non-member. Why is this not possible?

Because that's how operators are required to be defined: either
non-static members or non-members.
Since I want
to pass a private type of the class as argument, this is a problem.

What I tried to do is something like this:

#include<iostream>

using namespace std;

class Foo {
public:
void foo() {
#if 0
cout<< "yadda yadda "<< b<< endl;
#endif
}
private:
struct Bar {
public:
#if 1
static ostream&operator<<(ostream&os, const Bar&b)

Try replacing the keyword 'static' with 'friend'...
{
b.print(os);
return os;
}
#endif
private:
int bar;
void print(ostream&os) const { os<< bar; }
};

Bar b;
};

I cannot make the operator<< a non-member function since its parameter
type Bar is private and I'd prefer to leave it so. How should I solve
this?

Define a non-member operator << and make it call your static member
function (if that's what you need to access that static data member).
The alternative is to declare that non-member operator<< a friend.
When I replace the "operator<<" by some other function name the code
compiles but I still cannot use<< like in foo().

So, combine the two...

V
 
M

Marcel Müller

I tried overloading the operator<<() for ostream as a static member
function in a class, but the compiler (gcc) complained that it should
be non-static or non-member. Why is this not possible? Since I want
to pass a private type of the class as argument, this is a problem.
class Foo {
struct Bar {
public:
static ostream&operator<<(ostream&os, const Bar&b)
{
b.print(os);
return os;
}
I cannot make the operator<< a non-member function since its parameter
type Bar is private and I'd prefer to leave it so. How should I solve
this?

What's wrong with
friend ostream&operator<<(ostream&os, const Bar&b);
inside class Foo?


Marcel
 
U

Urs Thuermann

Marcel Müller said:
What's wrong with
friend ostream&operator<<(ostream&os, const Bar&b);
inside class Foo?

I am surprised that that works, because I have tried it before I
posted and gcc reported an error since the type Foo::Bar is private
and unusable outside class Foo. OK, I must have done something wrong,
since it now works, both, inline and outside of the class.

But now I've got the next question: How can I make that non-member
friend function static in foo.cc so it's not visible in other
translation units? (I know I can't use it anyway because I cannot
have object of type Foo::Bar, but I'd still prefer to have that
function staitc.)

When I try

friend static ostream &operator<<(ostream &os, const Bar &b);

in class Foo and

static ostream &operator<<(ostream &os, const Foo::Bar &b)
{
b.print(os);
return os;
}

outside any class in foo.cc I get the compiler message

error: storage class specifiers invalid in friend function declarations

and when I remove the static from the friend declaration I get

error: 'std::eek:stream& operator<<(std::eek:stream&, const Foo::Bar&)' was declared 'extern' and later 'static'

Without static in both places, everylooks looks fine.
But is there a way to have that operator<<() static?

urs
 
V

Victor Bazarov

I am surprised that that works, because I have tried it before I
posted and gcc reported an error since the type Foo::Bar is private
and unusable outside class Foo. OK, I must have done something wrong,
since it now works, both, inline and outside of the class.

But now I've got the next question: How can I make that non-member
friend function static in foo.cc so it's not visible in other
translation units? (I know I can't use it anyway because I cannot
have object of type Foo::Bar, but I'd still prefer to have that
function staitc.)

When I try

friend static ostream&operator<<(ostream&os, const Bar&b);

Drop the 'static'.
in class Foo and

static ostream&operator<<(ostream&os, const Foo::Bar&b)

Drop the 'static'.
{
b.print(os);
return os;
}

outside any class in foo.cc I get the compiler message

error: storage class specifiers invalid in friend function declarations

That's what your compiler is telling you: drop the 'static'.
and when I remove the static from the friend declaration I get

error: 'std::eek:stream& operator<<(std::eek:stream&, const Foo::Bar&)' was declared 'extern' and later 'static'
Huh?

Without static in both places, everylooks looks fine.

So, what's the problem?
But is there a way to have that operator<<() static?

WTF for?

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top