C++ lambda 不推断函数重载

标签 c++ lambda overloading

我正在定义一个这样的类:

class foo {
public:
  // I define const and non-const versions of the 'visit' function
  // nb. the lambda is passed by reference
  virtual void visitWith(std::function<void(foo&)>&);
  virtual void visitWith(std::function<void(const foo&)>&) const;
};
foo 可以有 child ,所以我们的想法是递归地访问 foo 及其所有 child 。
当我尝试使用它时,例如。像这样:
foo f;
f.visitWith([&](const foo&) {
  // Do something here
});
我得到编译器错误。编译器无法弄清楚该怎么做。
我可以通过添加这样的类型转换来使它工作:
foo f;
f.visitWith( (std::function<void(const foo&)>) [&](const foo&) {
  // Do something here
});
但这太可怕了。
我怎样才能让它整齐地工作?
编辑:
这可能是 Visual C++ 的问题,它拒绝编译此处给出的代码:
https://ideone.com/n9bySW
我尝试编译时的 VC++ 输出是:
I get this error in Visual C++
Edit2:不,Visual C++ 是正确的,代码不明确。请参阅下面的解决方案...

最佳答案

lambda 是编译器生成的类型,它不是 std::function 的实例,但它可以分配给一个。
您的 visitWith()方法采用 std::function通过非常量引用,这意味着它需要预先存在的 std::function对象,例如:

std::function<void(const foo&)> func = [&](const foo&) {
    // Do something here
};
foo f;
f.visitWith(func);
将 lambda 直接传递给 visitWith()将要求编译器创建一个临时的 std::function对象,但非常量引用不能绑定(bind)到临时对象。这就是您的原始代码无法编译的原因。
对于您正在尝试的内容,您必须通过 std::function通过值或 const-reference 代替:
class foo {
public:
    void visitWith(std::function<void(foo&)>);
    void visitWith(std::function<void(const foo&)>) const;
};
Live Demo
class foo {
public:
    void visitWith(const std::function<void(foo&)> &);
    void visitWith(const std::function<void(const foo&)> &) const;
};
Live Demo

关于C++ lambda 不推断函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64091573/

相关文章:

emacs - Emacs/Elisp 中的多态回调

C++ 重载返回 void 与非 void

c++ - 如何设计一个最近最近使用的缓存?

c++ - 无法在gdb中调用带有引用参数的函数

lambda - [SonarLint] : make this anonymous inner class a lambda

C++11 Lambda 表达式作为回调函数

c# - 如何使用 LINQ 从 IEnumerable 中选择随机项

c++ - 基于 bool 模板参数的重载

c++ - "Ü"的 UTF 编码返回 3 个字节而不是 "real"unicode

c++ - 如何在较大的强连通组件中找到强连通组件?