Хей. Поскольку бложиков не имею (задрали), а забавная штучка придумалась, оставлю тут, вдруг кому пригодится.
class Wrapper
{
protected:
struct FriendlyCall {};
};
class FriendshipReceiver
: private Wrapper
{
public:
void test1(const FriendlyCall& fc)
{
}
template<typename X>
void test2(const FriendlyCall& fc = X())
{
}
};
class FriendshipCaller
: private Wrapper
{
public:
void test()
{
FriendshipReceiver r;
r.test1(FriendlyCall()); // ok
r.test2<FriendlyCall>(); // ok
}
};
class BadCaller
{
public:
void test()
{
FriendshipReceiver r;
//r.test1(FriendlyCall());
//r.test2<int>(); // fail
//r.test2(); // fail
}
};
Примечание: здесь FriendshipCaller/FrienshipReceiver могут быть темплейтными, а для них нельзя делать friend class ...; По сути, здесь test*() - протектнутые функции, которые позволено вызывать снаружи некоторым избранным классам.