我有以下代码段:
struct Foo {
Foo(int num):num_(num){}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
};
int main() {
std::vector<Foo*> vpf{ new Foo(3), new Foo(4), new Foo(5) };
auto pfa = std::mem_fn(&Foo::print_add);
int i = 42;
//std::for_each(vpf.begin(), vpf.end(), [&i](const auto& val){val -> print_add(i);});
std::for_each(vpf.begin(), vpf.end(), pfa(&i));
return 0;
}
使用lambda表达式的注释代码实际上可以正常工作,因为我希望打印45,46,47。使用std::for_each
的{{1}}的未注释代码会导致编译错误mem_fn
。
有人可以解释为什么以及如何在这种情况下正确使用attempt to use a deleted function
?
答案 0 :(得分:1)
我看不出你怎么可能从这段代码中获得“尝试使用已删除的函数”错误。代码不准确,或者诊断消息不是列表中的第一个。
此代码中的第一个错误是指您的pfa(&i)
子表达式,该表达式无效。首先,为了调用 pfa
,您必须提供两个参数 - Foo *
和int
类型 - 而您只提供一个{{} 1}}类型。其次,在int *
的情况下,你根本不应该自己调用 std::for_each
,你应该传递 pfa
本身到pfa
。
如果你想用“lambdaless”替换你的lambda,例如使用“经典”std::for_each
功能对象,它看起来如下
std::mem_fn
或使用现已弃用的C ++ 98库功能
auto pfa = std::mem_fn(&Foo::print_add);
int i = 42;
std::for_each(vpf.begin(), vpf.end(), std::bind(pfa, std::placeholders::_1, i));
(那时候它只是......更加有趣。更多有趣 .Geddit?哈哈哈......)
PS 请注意(如评论中注明的@TC),如果您打算使用{{1},则无需预先将成员指针包装到auto pfa = std::mem_fun(&Foo::print_add);
int i = 42;
std::for_each(vpf.begin(), vpf.end(), std::bind2nd(pfa, i));
} 在上面。第一个变体可以重写为
std::mem_fn
答案 1 :(得分:0)
std::mem_fn
创建一个仿函数,它将引用或指向该类型的指针作为第一个参数,并将其余参数转发给实际函数。
将其传递给算法时,您不应该将其称为()
运算符(您没有为lambda示例执行此操作)。你的问题是你也想为你的函数提供一个参数,而这仅仅是mem_fn
是不可能的。不过,您可以使用std::bind
或lambda执行此操作。
std::for_each(vpf.begin(), vpf.end(), std::bind(pfa, std::placeholders::_1, i));
或
std::for_each(vpf.begin(), vpf.end(), [&i,&pfa](const auto& val){ pfa(val, i); });
话虽如此,我认为最好从你的例子中使用lambda。 bind
是有争议的,如果您还在使用lambda,那么将mem_fn
添加到其中的重点是什么?
答案 2 :(得分:0)
auto pfa = std::mem_fn(&Foo::print_add);
&Foo::print_add
不是函数指针。它是一个类方法指针。您不能将其作为函数指针调用。你必须为这个方法提出一个类的实例,并通过指针调用实例的方法。
std::for_each(vpf.begin(), vpf.end(), pfa(&i));
您正在尝试调用pfa
,就好像它是一个函数指针一样。首先,对于每次调用,std::for_each
都会按照迭代的顺序传递项目。这将成为您需要与方法指针一起使用的类实例:
std::for_each(vpf.begin(), vpf.end(),
[&i,&pfa](const auto& val){pfa(val, i);});
lambda获取其参数,序列std::for_each
中的值迭代,并使用它通过方法指针调用类方法。正如所料,此结果是
45
46
47