Reputation: 11509
This is something that normally works, but my use of namespaces is messing it up.
Take this code:
.h:
class FetchRecord
{
friend KxStream& operator<<( KxStream& os, FetchRecord& r );
protected:
int mId;
};
.cpp:
KxStream& operator<<( KxStream& os, FetchRecord& r )
{
os << r.mId;
return os;
}
This works fine. But if I do:
.h:
namespace Blah
{
class FetchRecord
{
friend KxStream& operator<<( KxStream& os, FetchRecord& r );
protected:
int mId;
};
}
.cpp:
using namespace Blah;
KxStream& operator<<( KxStream& os, FetchRecord& r )
{
os << r.mId;
return os;
}
Then the friend decl seems ignored:
src/fetch.cpp:153:25: error: 'mId' is a protected member of 'Blah::FetchRecord'
I can tell probably what is happening - the function in the .cpp does not match up with the function in the friend decl. How do you solve this?
@Update: Two correct answers below right now. Thanks. Tested and works. But I hate having to put my operator<< function in the Blah namespace. It would be cleaner if the full prototype for the function were:
KxStream& operator<<( KxStream&, Blah::FetchRecord& );
That is, if I could somehow forward declare that friend function outside of the namespace Blah. And I found a way:
namespace Blah
{
class FetchRecord;
}
KxStream& operator<<( KxStream& os, Blah::FetchRecord& r );
namespace Blah
{
class FetchRecord
{
friend KxStream& ::operator<<( KxStream& os, FetchRecord& r );
};
}
You have to get pendantically explicit. Note the "::" in the friend decl of operator<<.
Upvotes: 2
Views: 1712
Reputation: 41341
In the second case you define operator<<
in global namespace, it's unrelated to what you declared in .h file. You should define it in namespace Blah
:
namespace Blah {
KxStream& operator<<( KxStream& os, FetchRecord& r )
{
os << r.mId;
return os;
}
}
Update: if you want operator<<
to belong to global namespace (which is strange, because thanks to ADL it will work even without using namespace Blah
), you can write the following in .h file, and leave .cpp file as it is:
namespace Blah
{
class FetchRecord;
}
KxStream& operator<<( KxStream& os, Blah::FetchRecord& r );
namespace Blah
{
class FetchRecord
{
friend KxStream& ::operator<<( KxStream& os, FetchRecord& r );
// ^^^^
protected:
int mId;
};
}
Upvotes: 2
Reputation: 96865
Despite using namespace Blah
, you still need to qualify the name when defining the function because Blah
was the namespace in which it was declared. It should be:
KxStream& Blah::operator<<( KxStream& os, FetchRecord& r )
Upvotes: 1