【问题标题】:Call a member function using for_each使用 for_each 调用成员函数
【发布时间】:2013-08-02 00:06:38
【问题描述】:

这是我的原始代码

#include "stdafx.h"
#include <string>
#include <list>
#include <algorithm>
using namespace std;


class testing
{
public:
    int value;
    testing(int v)
    {
        value = v;
    }

    int getval()
    {
        return(value);
    }

};

void func(testing& ob)
{
    printf("The value is %d\n", ob.value);
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::list<testing> testvar[3];

    testing t1(0);
    testing t2(1);
    testing t3(3);

    testvar[0].push_back(t1);
    testvar[0].push_back(t2);
    testvar[0].push_back(t3);

    std::for_each(testvar[0].begin(), testvar[0].end(), func);

    printf("Reached End");
    getchar();
    return 0;
}

我修改它使 func 成为成员函数并得到奇怪的编译错误,我在网上搜索,有人告诉使用 bind1st,bind2nd

#include "stdafx.h"
#include <string>
#include <list>
#include <algorithm>
using namespace std;

class testing
{
public:
int value;
testing(int v)
{
    value = v;
}

int getval()
{
    return(value);
}

};

class testing2
{
public:
    std::list<testing> testvar[3];

    void func(testing& ob)
    {
        printf("The value is %d\n", ob.value);
    }

    void driver()
    {
        std::for_each(testvar[0].begin(), testvar[0].end(), func);
    }

};



int _tmain(int argc, _TCHAR* argv[])
{
    testing2 testob;

    testob.driver();


    printf("Reached End");
    getchar();
    return 0;
}

所以我把驱动函数修改成这个

    void driver()
    {
std::for_each(testvar[0].begin(), testvar[0].end(),     std::bind1st(std::mem_fun(&testing2::func), this));
    }

我仍然得到一些奇怪的编译错误,有人可以解释为什么我们需要调用成员函数是这样奇怪的方式..? bind1st 有什么帮助..?

【问题讨论】:

  • ssce 请人们在看到所有这些很可能是一个简单问题的代码时不太愿意回答
  • 我认为问题来自void func(testing&amp; ob)binder1st 的引用(bind1st 的返回类型)为operator() 提供了两个重载:一个采用const second_argument&amp; 和一个需要second_argument&amp;。作为mem_fun(..)(即mem_fun1_t)的返回类型的第二个参数已经是一个引用,因为func(testing&amp;)有一个引用operator()的这两个重载声明了一个函数相同的签名。
  • 为什么将func 设为成员函数?
  • 如果您可以使用 C++11 或 boost,您可以(并且应该)使用 sehe 的答案,否则您可以尝试 std::reference_wrapper(来自 TR1 或自己编写,很简单)作为函数的参数。

标签: c++ foreach-loop-container


【解决方案1】:

使用 std::bind

 std::for_each(testvar[0].begin(), testvar[0].end(), std::bind(&testing2::func, this, std::placeholders::_1));

或者使用 std::bind/lambdas

 std::for_each(testvar[0].begin(), testvar[0].end(), [this](testing& ob) { func(ob); });

完整:

#include <string>
#include <list>
#include <algorithm>
using namespace std;

struct testing {
    int value;
    testing(int v) { value = v; }
    int getval() { return(value); }
};

struct testing2 {
    std::list<testing> testvar[3];

    void func(testing& ob) {
        printf("The value is %d\n", ob.value);
    }

    void driver() {
        auto f = std::bind(&testing2::func, this, std::placeholders::_1);
        std::for_each(testvar[0].begin(), testvar[0].end(), f);
        std::for_each(testvar[0].begin(), testvar[0].end(), [this](testing& ob) { func(ob); });
    }
};

int main() {
    testing2 testob;
    testob.driver();
    printf("Reached End");
}

【讨论】:

  • C++11中也有std::mem_fn
  • @bennofs 我认为它不适用于这里,因为func 是不同类的非静态成员;需要绑定
【解决方案2】:

您还可以使用std::mem_fn 来获得更简洁的语法,如下所示:

std::for_each(testvar[0].begin(), testvar[0].end(), std::mem_fn(&testing::func));

完整代码:

#include <stdio.h>
#include <bits/stdc++.h>

class testing
{
public:
    testing(int v) : value(v) {}

    int getval() { 
        return(value);
    }

    void func()
    {
        printf("The value is %d\n", value);
    }

private:
    int value;
};

int main() {
    std::list<testing> testvar[3];

    testing t1(0);  
    testing t2(1);
    testing t3(3);

    testvar[0].push_back(t1);
    testvar[0].push_back(t2);
    testvar[0].push_back(t3);

    std::for_each(testvar[0].begin(), testvar[0].end(), std::mem_fn(&testing::func));

    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多