开发者

Is there any way to make for_each take references?

This cites for_each as follows:

  template<class InputIterator, class Function>
  Function for_each(InputIterator first, InputIterator last, Function f);

I have a collection std::list<std::string>, and a function void Do(std::string) works fine when given to for_each along with the iterators. But if I supply a function like void Do(std::string&), it does not compile. Is there a way around it? Or should I forget about it as some RVO like magic is going on? :D

EDIT:

bool PluginLoader::LoadSharedObjects()                              
{                                                              开发者_StackOverflow社区     
    for_each(l_FileNames.begin(), l_FileNames.end(), bind1st(mem_fun(&PluginLoader::LoadSharedObject),this));                                                                      
}   

void PluginLoader::LoadSharedObject(const std::string sFileName)   
{                                                                   
    void* pHandle = dlopen(sFileName.c_str(), i_LibMode);           
    //if(pHandle == NULL)
    //Check dlerror

    //Add handle to list
} 

Code added. I woul like LoadSharedObject function to be of the form void PluginLoader::LoadSharedObject(const std::string& sFileName) if it is possible.


The error is not with for_each but with bind1st and mem_fun. They simply dont't support what you're trying to do. They cannot handle functions which take reference parameters. You could write your own functor, use boost::bind or wait until you're able to use C++0x lambdas.

Example for your own functor:

struct LoadSharedObjFunctor
{
    PluginLoader *pl;
public:
    explicit(PluginLoader *p)
    : pl(p) {}

    void operator()(std::string const& cref) const
    { return pl->LoadSharedObject(cref); }
};

...
std::for_each(...,...,LoadSharedObjFunctor(this));
...

Of course, you don't have to use std::for_each. A simple for-loop will do as well.


If you are allowed to use boost, then what you want is boost:::bind.

#include <boost/bind.hpp>
...
for_each(l_FileNames.begin(),
         l_FileNames.end(),
         boost::bind(&PluginLoader::LoadSharedObject, this, _1)); 

Just for fun, here is why what you are trying doesn't work:

This mem_fun(&PluginLoader::LoadSharedObject) creates an object of type mem_fun1_t<void, PluginLoader, const string &>.

So bind1st(mem_fun(&PluginLoader::LoadSharedObject),this) creates an object of type binder1st< mem_fun1_t<void, PluginLoader, const string &> >.

The problem is that binder1st defines a function that looks like: ResultType operator()(const ArgType &), where ArgType is const string &. So effectively it means you are trying to form a reference to a reference.


The current standard isn't clear whether such usage of for_each should be allowed or not, and different implementations behave differently - some accept that but some not. That was considered unfortunate by some people, so C++0x is going to fix the situation by explicitly allowing mutating operations passed to for_each if the iterator is modifiable.

On the EDIT: const references aren't a problem. What errors do you get?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜