将 C++ 成员函数指针传递给 STL 算法
Posted
技术标签:
【中文标题】将 C++ 成员函数指针传递给 STL 算法【英文标题】:Passing a C++ Member Function Pointer to an STL Algorithm 【发布时间】:2015-05-20 15:56:41 【问题描述】:我有一个成员函数如下:
class XYZ
public:
float function(float x);
private:
float m_DensityMin;
float m_DensityMax;
;
现在,我正在尝试使用std::transform
STL 算法转换std::vector<float> foo
,方法是传递成员函数function
,并将结果值存储在向量bar
中。
如果我将该函数用作全局函数,使用应表示类的成员变量的随机数据,它可以正常工作。
但是,由于该函数需要使用类的成员变量m_DensityMin
和m_DensityMax
,所以我需要将其用作成员函数。这是我尝试过的:
std::transform(foo.begin(), foo.end(), bar.begin(), &XYZ::function);
但我最终在 VS2010 中出现错误:
error C2065: term does not evaluate to a function taking 1 arguments
据我所知,我只传递了 1 个参数。任何指针? 这是一个类似的question,我尝试过使用 std::mem_fun,因为我无法使用 std::mem_fn,但无济于事。
【问题讨论】:
“我尝试过使用 std::mem_fun,因为我无法使用 std::mem_fn,但无济于事。” 使用 @987654332 时出现了什么问题@?您是否尝试过使用 lambda? 除非它是一个静态函数,否则您需要一个参数对象,并将其绑定到mem_fun
返回的任何内容:std::transform(foo.begin(), foo.end(), std::back_inserter(bar), std::bind1st(std::mem_fun(&XYZ::function), &xyz));
, demo
function
应该是静态成员函数。
@Piotr 非常感谢,成功了!
@ccoder83 VS2010有mem_fn
,试试std::tr1::mem_fn
【参考方案1】:
std::mem_fun
本身只为成员函数提供了一个包装器,因此将在传递给其operator()
的第一个参数的上下文中调用它。话虽如此,在将函数对象传递给std::transform
算法之前,您需要bind 的正确实例XYZ
:
XYZ xyz;
std::transform(foo.begin(), foo.end(),
std::back_inserter(bar),
std::bind1st(std::mem_fun(&XYZ::function), &xyz));
// ~~~~~~^ ~~~~~~^ ~~~^
DEMO
【讨论】:
【参考方案2】:除非函数是static
,否则它需要一个类的实例来调用函数。因为非静态函数应该依赖于该类的内部状态。如果函数独立于类的状态,它可能应该是静态的。
如果您必须按原样保留您的课程,您可以默认构造一个 XYZ
来解决这个问题,只是为了有一个实例来调用函数。
std::transform(foo.begin(),
foo.end(),
std::back_inserter(bar),
[](float a) return XYZ.function(a); );
但这感觉很hacky,如果函数不依赖于XYZ
实例的状态,我希望函数是static
,并且只依赖于输入float
。
【讨论】:
foo
是 vector<float>
,而不是 vector<XYZ>
。
比起 std::bind,我更喜欢 lambda 版本。我实际上忘记了 std::bind ,因为我学习了 lambda,现在我更快乐了!我也喜欢您在适当位置创建微小对象的事实,尽管如果它的大小相关,通过引用捕获它可能会更好。
如果函数依赖于 XYZ 实例的状态,您可以使用 lambda 绑定到您调用 std::transform 的同一个 XYZ 实例。 std::transform(foo.begin(), foo.end(), std::back_inserter(bar), [this](float a) return this->function(a); )
【参考方案3】:
lambda 版本
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";
【讨论】:
以上是关于将 C++ 成员函数指针传递给 STL 算法的主要内容,如果未能解决你的问题,请参考以下文章