如何调用一个函数,该函数的每个循环都有一个for_的参数? 我有一个C++程序,它将对象存储在向量中,然后使用 STD::FoYUng/来调用每个对象上的函数。如果调用的函数需要获取参数,我不知道如何编写std::for_each循环

如何调用一个函数,该函数的每个循环都有一个for_的参数? 我有一个C++程序,它将对象存储在向量中,然后使用 STD::FoYUng/来调用每个对象上的函数。如果调用的函数需要获取参数,我不知道如何编写std::for_each循环,c++,foreach,C++,Foreach,下面是我希望使用的代码示例: #include <vector> #include <algorithm> #include <functional> class BaseClass { public: virtual void Setup() = 0; virtual void DisplayText(int key, int x, int y) = 0; }; class A: public BaseClass

下面是我希望使用的代码示例:

#include <vector>
#include <algorithm>
#include <functional>

class BaseClass
{
    public:
        virtual void Setup() = 0;
        virtual void DisplayText(int key, int x, int y) = 0;
};

class A: public BaseClass
{
    public:
        void Setup();
        void DisplayText(int key, int x, int y);
};

class B: public BaseClass
{
    public:
        void Setup();
        void DisplayText(int key, int x, int y);
};

void demo(A *a, B *b, std::vector<BaseClass*>& storageVector)
{
    storageVector.push_back(a);
    storageVector.push_back(b);

    std::for_each (storageVector.begin(), storageVector.end(),
        std::mem_fn(&BaseClass::Setup));

    std::for_each (storageVector.begin(), storageVector.end(),
        std::mem_fn(&BaseClass::DisplayText));
}
然后我也得到了

error C2352: 'BaseClass::DisplayText' :
    illegal call of non-static member function

我缺少什么?

从cppreference.com,函数的签名应该是
void-fun(const-Type&a)
。我认为问题可能是您的签名不接受任何参数(在
设置
的情况下)或多个参数(在
显示文本
的情况下),这不是每个的
所期望的

您可能需要:

void my_func(const BaseClass &r_arg) {};

可以使用lambda函数

std::for_each (storageVector.begin(), storageVector.end(), [] (BaseClass* base) {base->Setup();});
std::for_each (storageVector.begin(), storageVector.end(), [] (BaseClass* base) {base->DisplayText(1, 2, 3);});

有关lambda函数的更多信息,请访问。

函数
DisplayText
需要三个未提供的附加参数。您需要:

DisplayText
更改为不需要任何参数

或者使用提供以下功能的lambda:

for_each(storageVector.begin(), storageVector.end(),
   [](BaseClass* c){ c->DisplayText(key, x, y); });
for (auto c : storageVector)
    c->DisplayText(key, x, y);
或用于提供它们的每个循环:

for_each(storageVector.begin(), storageVector.end(),
   [](BaseClass* c){ c->DisplayText(key, x, y); });
for (auto c : storageVector)
    c->DisplayText(key, x, y);
或将参数绑定到函子:

for_each(storageVector.begin(), storageVector.end(),
    std::bind(std::mem_fn(&BaseClass::DisplayText), _1, key, x, y));

您需要将一些参数绑定到函数
DisplayText
,该函数包含3个参数
key
x
y
。有多种方法可以做到这一点。例如,您可以创建自己的进行绑定的函子对象,也可以使用lambda

最简单的方法是将常量值绑定到参数,但也可以绑定基于某些外部信息计算的值。无论哪种方式,都不能在不提供其所有参数的情况下调用
DisplayText

在第二个示例中,您尝试使用参数“获取函数的地址”。你不能直接在C++中做这件事。其他一些语言直接允许您绑定一些数量小于函数实际声明参数数量的参数,这个概念称为currying。在不支持此功能的语言中,典型的方法是使用闭包来存储附加参数的状态,并允许稍后调用闭包。这个功能是C++11的lambda所支持的

for_每个
都需要一个只接受一个参数的函数,但您给它的是不同的参数,这就是您的错误所表明的
std::mem_fn
接受一个成员函数,并将其转换为接受附加参数的非成员可调用对象。这意味着您现在为每个_提供了
,它需要4个参数而不是1个参数。第一个参数是要调用的对象,另外三个参数是
DisplayText
期望的原始参数

我将向您展示FrimultObjor方法,因为即使在C++的旧版本中,这也会起作用,实际上它是<>代码> STD::函数< /> >和lambda对象在覆盖之下工作的方式。C++11有新的语法,可以更简洁地执行此操作,但了解它的工作原理对于理解新语法非常有用

class F {
public:
    F(int key, int x, int y) : key(key), x(x), y(y) {}

    void operator()(BaseClass *d) const {
        d->DisplayText(key, x, y);
    }

private:
    int key;
    int x;
    int y;
};

for_each(storageVector.begin(), storageVector.end(), F(1, 2, 3));

如果您这样做,您会发现自己编写了很多这样的一次性类,它们所做的只是存储一些给定数量的带有特定类型签名的参数。认识到这一点,您可以通过模板化参数的类型来泛化这个类。再进一步,您可以通过获取可变数量的模板参数,从而支持可变数量的参数,对其进行更广泛的概括。这正是
std::function
类型的工作方式。

错误通常与行号一起出现。你的朋友会那样做吗?它们对应于哪些行?在每个循环的第2行中,DisplayText方法应该接收声明中宣布的3个参数。也许这是个问题。@MarcusMüller它说错误在文件中。肯定是我没碰过的文件。所有这些都是在我的源代码中写的。你能支持c++11语法吗?在c++11中,您尝试执行的操作要容易得多。@如果它尝试添加导致此错误的值,则平均值为:错误C2352:“BaseClass::DisplayText”:非法调用非静态成员函数。我在问题中添加了这些信息。我不知道如何正确地添加参数。这是我尝试过的,但没有成功:for_each(storageVector.begin()、storageVector.end()、std::mem_fn(&BaseClass::DisplayText(0,0,0));)那个自动循环正是我让它工作所需要的。非常感谢你的回答!我也添加了这种可能性,我不知道lambda函数。那些真的很漂亮。当我尝试将其添加到main时,尽管它给出了以下错误:IntelliSense:封闭函数局部变量不能在lambda主体中引用,除非它在捕获列表中。你知道为什么会这样吗?lambda函数通过使用语法
[=](BaseClass*base){}
捕获其封闭范围内的所有内容。它们还可以使用
[a,b](基类*base){}
从封闭范围中捕获特定名称。我只需要在方括号中添加变量。那就行了。整洁的谢谢你的回答。