I know the general use cases for the friend
keyword with regards to encapsulation but one a couple of occasions, I have needed the friend
keyword just to "get the job done". These use cases don't make me happy so I'm wondering if there are some alternatives. Here's the first minimal example:
struct Foo{
enum class Bar{
a=1,b=2,c=4
};
// need to tell the compiler of operator| before it gets used
// but it can't be a member function of Foo: so add friend keyword
friend Bar operator|(const Bar& b1, const Bar& b2);
// constructor needs a default value using
// operator| for Bars
Foo( Bar b = Bar::a | Bar::b );
};
// definition of operator|, etc.
Is there any way for the compiler to see the declaration of the operator|
for the nested class, inside of interface, before the default values are given at the Foo
constructor declaration?
I also sometimes find myself using the friend
keyword in defining symmetric operations of nested classes within templates. For example:
template<typename T>
struct A{
struct B{
friend bool operator==(const B& x, const B& y) { return true; }
};
};
The operator==
does not require friendship from an encapsulation perspective. But due to operator==
not actually being a templated function and the compiler being unable to deduce the types of nested classes within templates, this seems to be the only reasonable "trick" to keep operator==
as a free function.
As I said, these choices do work, but I'm wondering if there are better choices/practices out there.