为什么 mem_fn() 抱怨尝试使用已删除的函数
why does mem_fn() complain about attempt to use a deleted function?
我有以下代码片段:
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 工作。使用mem_fn
的带有std::for_each
的未注释代码会导致编译错误attempt to use a deleted function
。
有人可以解释为什么以及如何在这种情况下正确使用mem_fn
吗?
我不明白您如何从此代码中获得"尝试使用已删除的函数"错误。代码不准确,或者诊断消息不是列表中的第一个。
此代码中的第一个错误将引用您的 pfa(&i)
子表达式,该子表达式无效。首先,为了调用pfa
您必须提供两个参数 - Foo *
和int
类型 - 而您只提供int *
类型中的一个。其次,在std::for_each
的背景下,你根本不应该自己打电话给pfa
,你应该pfa
本身传递给std::for_each
。
如果你想用"lambdaless"替换你的lambda,例如使用"classic"std::mem_fn
函数对象,它看起来像这样
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));
或者,使用现已弃用的 C++98 库功能
auto pfa = std::mem_fun(&Foo::print_add);
int i = 42;
std::for_each(vpf.begin(), vpf.end(), std::bind2nd(pfa, i));
(当时只是...不知何故更有趣。更有趣。盖迪特?哈...
附言请注意(如 @T.C. 在注释中指出的那样(,如果您打算在其上使用 std::bind
,则无需通过 std::mem_fn
预先包装成员指针。第一个变体可以重写为
int i = 42;
std::for_each(vpf.begin(), vpf.end(),
std::bind(&Foo::print_add, std::placeholders::_1, i));
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
有什么意义呢?
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
- 为什么我的双向链表删除函数会删除多个节点?
- unique_ptr实现接口时对已删除函数的引用
- 可视代码 删除函数括号内的空格
- 从尝试引用已删除函数的矢量 C++ 中删除对象
- 试图引用已删除函数数组的相等运算符
- 双链表堆栈删除函数不起作用
- 是否需要删除函数中未使用的新结构?
- C++引用已删除函数错误
- 删除函数环境中C++输入 R 对象
- 删除函数中的对象C++
- 在 C++ 中使用删除函数的不同方式
- C++错误:C2280 - 引用已删除函数的编译器错误?
- C++,删除函数/迭代进程中定义的动态数组
- 删除函数 c++ 的读取访问冲突异常
- 如何对此自定义C 列表类实现删除函数
- 双向链表问题(特别是复制构造函数和删除函数)
- 引用 std::atomic <bool>的已删除函数错误
- 在删除函数自由度的指针后,为什么我会得到核心转储
- C++删除函数
- 返回 C++11 中已删除函数的类型