Is there any way to make for_each take references? - c++

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()
{
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?

Related

Is there a single-input, binary output stdlib or boost function I can bind to?

bool all_ok = boost::algorithm::all_of(info.begin(), threadInfo.end(), [&](std::pair<std::string, Info> const &p){ return p.second.am_ok; });
Above is a line I am trying to remove c++11 from (in order to be compliant with an application I am integrating with, if you must know). I would like to replace the lambda without defining a function external to the current method.
My question is, how can I utilize boost::bind to represent a function & binding that takes in a single input and returns a boolean?
If you really want to use boost::bind to do this, it would look something like this:
boost::bind(&Info::am_ok, boost::bind(&std::pair<std::string, Info>::second, _1));
Boost.Bind supports composition of its function objects, so in this case the function object created by the nested bind gets called first, and its result (the Info object) is passed to the enclosing function object, which returns the am_ok member of the structure.
You see that the code is somewhat contrived, so you'll probably want to write a custom function object anyway.
struct is_ok
{
typedef bool result_type;
result_type operator() (std::pair<std::string, Info> const &p) const
{
return p.second.am_ok;
}
};

which container to use map or set or else?

If using std::map<std::string,object> to keep objects ordered by name, the map's value_type (std::pair<string,object>) is a convenient class which warrants useful functionality, e.g.
typedef std::map<std::string,object> object_map;
typedef typename object_map::value_type named_object;
void function(named_object const&);
// with the following possible use case
void foo(std::string const&name, object_map const &omap)
{
auto obj=omap.find(name);
if(obj==omap.end()) throw std::runtime_error("name not found");
function(*obj);
}
So far, so good. I later extend my objects
struct extended_object : object { /* more data */ };
and keep the extended objects ordered by name, too, via std::map<std::string,extended>.
I may define.
typedef std::map<std::string,extended_object> extended_object_map;
typedef typename extended_object_map::value_type named_extended_object;
Unfortunately, I cannot
void foo(std::string const&name, extended_object_map const& emap)
{
auto eobj=emap.find(name);
if(eobj==emap.end()) throw std::runtime_error("name not found");
function(*eobj); // cannot convert *eobj to const named_object&
}
Now, my question is how to solve this problem? I considered using a reinterpret_cast<>
function(reinterpret_cast<const named_object&>(*eobj));
which essentially assumes that the data layouts of named_object and named_extended_object are exactly like that of base and derived. Is this safe/recommendable?
Alternatively, I considered to use std::set (instead of std::map) with key types
named_object and re-define
struct named_extended_object : named_object { /* more data */ };
The problem with this approach is that in order to std::set::find() an object, I must provide not just a name string, but a whole object or even extended object. According to cppreference, std::set::find() will have a resolution to this problem in C++14 (overloads 3&4), but what shall I do in the mean time?
Change your function to
void function(const std::string& name, const object& obj);
Then call it like
auto obj = omap.find(name);
function(obj->first, obj->second);
// or
auto eobj = emap.find(name);
function(eobj->first, eobj->second);
the map's value_type (std::pair<string,object>) is a convenient class which warrants useful functionality
N.B. that is not the map's value_type. It's std::pair<const string,object>
The reinterpret_cast results in undefined behaviour when a named_extended_object is accessed through the reference, it violates what some compilers call "strict aliasing" rules, and can cause your program to misbehave if the compiler optimises using type-based alias analysis. Do not use reinterpret_cast like that. In handwavy Liskov Substitution Principle terms, extended_object IS-A object, so it's OK to substitute an extended_object where an object is expected, but pair<T, extended_object> IS-NOT-A pair<T, object> so cannot be used interchangeably.
I like D Drmmr's answer, but if you don't want to do that, another option is a template:
template<typename Obj>
void function(const std::pair<const std::string, Obj>&)
{
// ...
}
This will accept pair<const string, object> and also pair<const string, extended_object> arguments. If the body of the template only tries to access the members that are present in object then it will work perfectly for both argument types.
If you don't want to expose that template to users of the function, then declare two overloads:
void function(const named_object&);
void function(const named_extended_object&);
Then in the implementation file:
namespace {
template<typename Obj>
void function_impl(const std::pair<const std::string, Obj>&)
{
// common implementation ...
}
}
void function(const named_object& no) { function_impl(no); }
void function(const named_extended_object& neo) { function_impl(neo); }

Using STL to bind multiple function arguments

In the past I've used the bind1st and bind2nd functions in order to do straight forward operations on STL containers. I now have a container of MyBase class pointers that are for simplicities sake the following:
class X
{
public:
std::string getName() const;
};
I want to call the following static function using for_each and binding both the 1st and 2nd parameters as such:
StaticFuncClass::doSomething(ptr->getName(), funcReturningString() );
How would I use for_each and bind both parameters of this function?
I'm looking for something along the lines of:
for_each(ctr.begin(), ctr.end(),
bind2Args(StaticFuncClass::doSomething(),
mem_fun(&X::getName),
funcReturningString());
I see Boost offers a bind function of its own that looks like something that would be of use here, but what is the STL solution?
Thanks in advance for your responses.
A reliable fallback when the bind-syntax gets too weird is to define your own functor:
struct callDoSomething {
void operator()(const X* x){
StaticFuncClass::doSomething(x->getName(), funcReturningString());
}
};
for_each(ctr.begin(), ctr.end(), callDoSomething());
This is more or less what the bind functions do behind the scenes anyway.
The "STL solution" would be to write your own binder... that's why they created the powerful boost::bind.
You can either create a local functor structure, which can be inlined by the compiler (as Jalf showed), or use a simple function:
void myFunc( const X* x ) {
StaticFuncClass::doSomething(x->getName(), funcrReturningString() );
}
for_each( c.begin(), c.end(), myFunc );

How do you pass boost::bind objects to a function?

I have a one-dimensional function minimizer. Right now I'm passing it function pointers. However many functions have multiple parameters, some of which are held fixed. I have implemented this using functors like so
template <class T>
minimize(T &f) {
}
Functor f(param1, param2);
minimize<Functor>(f);
However the functor definition has lots of crud. Boost::bind looks cleaner. So that I could do:
minimize(boost:bind(f,_1,param1,param2))
However I'm not clear what my minimize declaration should like like using boost::bind. What type of object is boost::bind? Is there an easy pattern for this that avoids the boilerplate of functors but allows multiple parameter binding?
You can just use boost::function. I think boost::bind does have its own return type, but that is compatible with boost::function. Typical use is to make a typedef for the function:
typedef boost::function<bool(std::string)> MyTestFunction;
and then you can pass any compatible function with boost::bind:
bool SomeFunction(int i, std::string s) { return true; }
MyTestFunction f = boost::bind(SomeFunction, 42, _1);
f("and then call it.");
I hope that is what you want.
It also works with methods by passing the this pointer for the call as second parameter to boost::bind.
I would define minimize() this way:
minimize(boost::function< return_type(param_type1,param_type2,param_type3,...)> f)
{
...
}
Then you could call minimize() like this:
minimize(boost::bind(&class::function,actual_object,_1,_2,_3,...));
Change the parameter to a value parameter. Function objects are intentionally light weight, and boost::bind certainly is, specially crafted to fit in within space of a few bytes using boost::compressed_pair and what not.
template <class T>
void minimize(T f) {
}
Then you can pass it the result of boost::bind. Remember that boost::bind is actually a function template that returns some object of some type. So having minimize have a non-const reference parameter couldn't work.
First, you are taking your template argument as a ref-to-non-const, so the temporary returend by boost::bind won't bind to it. So you can use it like:
template <class T>
T::result_type minimize(const T &f) {
}
But if you wanted to use this with your Functors as well, they would have to have a const operator(). So perhaps by value is better:
template <class T>
T::result_type minimize(T f) {
}
I believe having the return be T::result_type will force a T to be a boost::function (rather than the complicated type bind returns), but I'm not 100%

Polymorphic functors in std::for_each

I'm trying to use stl algorithm for_each without proliferating templates throughout my code. std::for_each wants to instantiate MyFunctor class by value, but it can't since its abstract. I've created a functor adapter class which passes a pointer around and then derefernces it when appropriate.
My Question:
Does the STL or Boost already have such an adapter class? I don't want to have to reinvent the wheel!
struct MyFunctor {
virtual ~MyFunctor() {}
virtual void operator()(int a) = 0;
}
namespace {
template<typename FunctorType, typename OperandType> struct
FunctorAdapter
{
FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
void operator()(OperandType& subject)
{
(*mFunctor)(subject);
}
FunctorType* mFunctor;
}; }
void applyToAll(MyFunctor &f) {
FunctorHelper<MyFunctor, int> tmp(&f);
std::for_each(myvector.begin(), myvector.end(), tmp); }
Cheers,
Dave
You could use the function adapters (and their shims) from functional.
#include <functional>
using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );
If your container contains pointers-to-objects, use mem_fun_ptr, else use mem_fun. Next to these, there are wrappers for member functions that take 1 argument: mem_fun1_ptr and mem_fun1.
#Evan: indeed, you could call the member function with the same argument for each object. The first argument of the mem_fun1 wrappers is the this pointer, the second is the member function argument:
for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );
With more arguments, it becomes more readable to create a loop yourself, or create a custom functor that has const member variables representing the arguments.
tr1::ref may help you here --- it's meant to be a reference wrapper so that you can pass normal objects by reference to bind or function objects (even abstract ones) by reference to standard algorithms.
// requires TR1 support from your compiler / standard library implementation
#include <functional>
void applyToAll(MyFunctor &f) {
std::for_each(
myvector.begin(),
myvector.end(),
std::tr1::ref(f)
);
}
However, NOTE that compilers without decltype support MAY reject passing a reference to an abstract type... so this code may not compile until you get C++0x support.
why not use BOOST_FOREACH?
http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html
Sounds like you could benefit from Boost::Function.
If I remember correctly it's a header only library too, so it's easy to get it going with it.
What about forgetting all the wrapping of the functor pointer, and instead use
bind(functor_pointer,mem_fun1(&MyFunctor::operator());
as the functor? that way, you don't have to worry about managing the copy in any way shape or form.
Building on #xtofl's answer, since the array contains int's and not "this" pointers, I think the correct incantation is
class MyClass
{
virtual void process(int number) = 0;
};
MyClass *instance = ...;
for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );
The only difference versus #xtofl's code is binder1st rather than binder2nd. binder2nd allows you to pass teh same number to various "this" pointers. binder1st allows you to pass various numbers to one "this" pointer.