Using friendship to grant access to std::begin
and std::end
will not provide any benefits. Other code will be free to use them to gain access to the adapters iterators making the whole approach useless. Eventually it ends up like MySpace and nobody wants to use it anymore. Eventually you end up like Facebook with everyone abusing it and doing things you don't want them to do.
The only option for handling begin/end would be to grant access to individual classes and free functions through friendship. Unfortunately this will impose limitations on its use and will require updating every time you want to grant access to additional functions. The following example highlights the futility of using friendship to give access to a free function like std::begin
class Restricted
{
int begin() { return 0; }
friend int std_begin(Restricted&r);
};
int std_begin(Restricted&r)
{
return r.begin();
}
int main()
{
Restricted building;
// Side step private! might as well just call building.begin()
int it = std_begin(building);
}
[Old unneeded answer left for historical insignificance]
If you want to limit access I recommend implementing for_each
as one or more member functions of the class. This takes a functor as one of the parameters and iterates through the container. This makes it generally available to anyone that wants to use it while still imposing restrictions on accessing data. The following example provides a for_each
function and a functor to play with.
#include <iostream>
#include <vector>
class Adapter
{
public:
template<typename FuncType>
void for_each(FuncType &func)
{
for(std::vector<int>::iterator it = data_.begin();
it != data_.end();
++it)
{
// Pass by value (prevent modification)
// you can pass the iterator as is if you like!
func(*it);
}
}
//private: we leave it public for demo purposes
std::vector<int> data_;
};
int main()
{
Adapter cnt;
cnt.data_.push_back(1);
cnt.data_.push_back(2);
cnt.data_.push_back(3);
cnt.data_.push_back(4);
struct {
void operator()(int value) {
std::cout << value << std::endl;
}
} for_function;
cnt.for_each(for_function);
}
You will want to add const qualified versions of the for_each
function and possible a few overloads with different number of parameters depending on your requirements. With C++11 you have the option of passing a lambda or using std::function
and you can also use components included in Boost.