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?
精彩评论