将c++成员函数指针传递给STL算法

Passing a C++ Member Function Pointer to an STL Algorithm

本文关键字:STL 算法 指针 c++ 成员 函数      更新时间:2023-10-16

我有一个成员函数如下:

class XYZ{
public:
    float function(float x);
private:
    float m_DensityMin;
    float m_DensityMax;
};

现在,我试图通过传递成员函数function来使用std::transform STL算法转换std::vector<float> foo,并将结果值存储在向量bar中。

如果我将函数用作全局函数,并使用随机数据表示类的成员变量,则可以正常工作。

但是,由于函数需要使用类的成员变量m_DensityMinm_DensityMax,所以我需要将其作为成员函数使用。这是我尝试过的:

std::transform(foo.begin(), foo.end(), bar.begin(), &XYZ::function);

,但我最终与错误在VS2010:

error C2065: term does not evaluate to a function taking 1 arguments

据我所知,我只传递了一个参数。指针吗?这里有一个类似的问题,我尝试过std::mem_fun,因为std::mem_fn对我来说不可用,但无济于事。

std::mem_fun本身仅为成员函数提供包装器,因此将在传递给其operator()的第一个参数的上下文中调用成员函数。话虽如此,在将函数对象传递给std::transform算法之前,您需要绑定XYZ的适当实例:

XYZ xyz;
std::transform(foo.begin(), foo.end(),
               std::back_inserter(bar),
               std::bind1st(std::mem_fun(&XYZ::function), &xyz));
//                  ~~~~~~^      ~~~~~~^                  ~~~^

除非函数是static,否则它需要一个类的实例来调用该函数。因为非静态函数应该依赖于该类的内部状态。如果函数独立于类的状态,那么它应该是静态的。

如果你必须让你的类保持原样,你可以通过默认构造一个XYZ来绕过这个问题,只是为了有一个实例来调用函数。

std::transform(foo.begin(),
               foo.end(),
               std::back_inserter(bar),
               [](float a){ return XYZ{}.function(a); });

但这感觉很hacky,我宁愿函数是static,如果它不依赖于XYZ实例的状态,只依赖于输入float

lambda version

std::vector<float> foo;
std::vector<float> bar;
foo.push_back(1.0f);
foo.push_back(2.0f);
XYZ xyz;
std::transform(foo.begin(), foo.end(), std::back_inserter(bar), 
        [&xyz](float& a){ return xyz.function(a); });
 for ( auto & x : bar)
   std::cout<<x<<"n";