Use-declaration for friend function

In C ++ 11, you can make a public member of a private base class available to the public with a using declaration. for example

 class A { private: int i = 2; public: void f() { i = 3; } friend bool operator==(const A& l, const A& r) { return li == ri; } }; class B : private A { public: using A::f; }; int main() { B b, b2; bf(); } 

bf() probably due to using A::f in the definition of B

Is it possible to write a similar declaration that would make the effect from B& to A& possible for the friend function operator==(A&, A&) , so that b == b2 can be called in main() ?

+7
c ++ c ++ 11 friend using c ++ 14
source share
1 answer

No, only B can embed itself in A , and otherwise this is not possible, since from the point of view of client B A , but rather has A

Even if you replaced friend bool operator= with a member function equals :

 class A { private: int i = 2; public: void f() { i = 3; } bool equals(const A& r){return i == ri;} }; class B : private A { public: using A::f; using A::equals; }; 

While this is compiling, you can never call b.equals(b2) , because it is not possible to implicitly convert from type B to type A from the perspective of the caller (due to private inheritance).

You will need to provide your own operator== or change your inheritance to public or protected . Here's an example where B declares its own friend bool operator==

 class B : private A { public: using A::f; friend bool operator==(const B& l, const B& r) { return (static_cast<A>(l) == static_cast<A>(r)) && true; // "true" is a stand-in for some other condition } }; 

More at isocpp


Edit: If you really want to play games, you will notice that I said that no implicit conversion will ever be possible, but some explicit conversions. Since B technically derived from A , you can cast with a pointer to make it work, but I do not recommend:

 class A { private: int i = 2; public: void f() { i = 3; } bool equals(const A* r){return i == r->i;} }; class B : private A { public: using A::f; using A::equals; }; int main() { B b, b2; bf(); (::A*)(&b)->equals((::A*)(&b2)); } 

Or you could use the ugly cousin evasion decree, link casting if you want to keep the original syntax operator==

 class A { private: int i = 2; public: void f() { i = 3; } friend bool operator==(const A& l, const A& r) { return li == ri; } }; class B : private A { public: using A::f; }; int main() { B b, b2; bf(); ((::A&)(b)) == ((::A&)(b2)); } 

See Β§11.2 [class.access.base] for more

+4
source share

All Articles