我在将std::for_each和其他算法与多图一起使用时遇到困难,并且想知道是否有人可以帮助我开发可以将适当的参数传递给“泛型”函数的函子。

我对map / multimap的具体问题是,它们的迭代器求值是std::pair而不是需要使用的包含值(我的意思是,mapped_type)。因此,我的问题是,是否有一种方法可以将适当的值传递给旨在与所包含的map / multimap类型之一一起使用的函数?

这是我的示例代码:

// the key type for the multimap
typedef enum { ... } Module;

// my class as the mapped type for the multimap
struct Patch
{
    void Apply(bool enable);
}

// I have some functors designed to work directly with Patch pointers
// because in other places I use set<Patch*> or other containers
struct ApplyOnCondtion: public unary_function<Patch*, void>
{
    void operator() (Patch* patch)
    {
        if(some_condition) patch->Apply(enable_or_not);
    }
}

// somewhere I have a collection of patches attributed to some module
multimap<Module, Patch*> patches;

// the problem is that using for_each with a map or a multimap results in
// a `pair<Module,Patch*>` as argument to the functor, not the Patch* as desired.
for_each(patches.begin(), patches.end(), ApplyOnCondition(...));

我认为也许bind1st或bind2nd与mem_fun结合可以解决此问题,或者我可以想到的另一种方法是创建一个新的函子,该函子存储原始函子并传递对中的正确成员,但我不是设法取得任何好的结果。有STL经验的人可以提供一些建议吗?
EDIT 1

好的,在不使用boost或其他临时容器的情况下,我能得到的最好的结果是:
#include <functional>
#include <utility>
using namespace std;


//////////////////////////////////////////////////////////////////////////
// any functor to be called must be derived from unary_function or
// have defined result_type and argument_type.
// template 'First' should be set to pair::first_type
template<typename First, typename Func>
class passSecond_t: public unary_function<
                        pair<First,typename Func::argument_type>,
                        typename Func::result_type>
{
    Func* func;

public:
    passSecond_t(Func &functor): func(&functor) {}

    result_type operator()(argument_type value)
    {
        return (*func)(value.second);
    }
};

// construction helper, unfortunately 'First' must be explicitly specified
template <typename First, typename Func>
passSecond_t<First, Func> passSecond(Func& functor)
{
    return passSecond_t<First, Func> (functor);
}


// the following is a sample
#include <map>
#include <algorithm>
#include <iostream>

struct SampleClass
{
    void execute(char* text)
    {
        cout << "this: " << this << ", text: " << text << endl;
    }
};

struct SampleFunctor: public unary_function<SampleClass*,void>
{
    char* text;
    SampleFunctor(char* text_): text(text_) {}

    result_type operator() (argument_type argu)
    {
        argu->execute(text);
    }
};

void main()
{
    map<int,SampleClass*> mymap;
    SampleClass s1, s2;
    mymap[0] = &s1;
    mymap[1] = &s2;

    SampleFunctor myfunctor("my text");

    for_each(mymap.begin(), mymap.end(), passSecond<int>(myfunctor));
}

最佳答案

一开始我有一个增强的解决方案:

for_each(patches.begin(), patches.end(),
         boost::bind(ApplyOnCondition(...),
                     boost::bind(&map_type::value_type::second, _1)));

这将获取该对中的:: second成员,并将其向前推送到ApplyOnCondition的operator()。 map_type是 map 的类型(当然是multimap<Module, Patch*>)。

10-07 19:16
查看更多