Yes there is.
I've been trying to advocate the method for a while now, the basic idea is to use a Key
class.
While this does not actually remove the use of friend
, it does reduce the set of exposed implementations details.
class set;
// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };
class set
{
// 2. Define the iterator
class iterator
{
public:
void public_method();
void restricted_method(set_key&);
}; // class iterator
}; // class set
Now, restricted_method
is public, so set
does not need any special access to iterator
. However the use of it is restricted to those able to pass a set_key
instance... and conveniently only set
may build such an object.
Note that set
may actually pass a set_key
object to someone else it trusts. It is a key in the traditional sense: if you give a key of your flat to someone, it may entrust it to another person. However because of the semantics of the key class (non copyable, only set
may construct and destroy it) this is normally limited to the duration of the scope of the key
object.
Note that a evil hack is always possible, namely *((set_key*)0)
. This scheme protects from Murphy, not Machiavelli (it's impossible in C++ anyway).