【问题标题】:Const reference parameter in lambda functionlambda 函数中的 const 引用参数
【发布时间】:2020-03-12 09:32:00
【问题描述】:
#include <iostream>
#include <functional>

using Callback = std::function<void(const int)>;

int main() {
    Callback testCall = [](const int &num) {
        std::cout << "callback: " << num << " - " << &num << std::endl;
    };
    int num = 42;
    testCall(num);
    std::cout << "main:     " << num << " - " << &num << std::endl;
}

可能的输出:

callback: 42 - 000000B19197F618
main:     42 - 000000B19197F694

如您所见,即使我分配了一个通过引用获取参数的 lambda 函数,它仍然使用副本。

对吗?

如果是,为什么它仍然编译?为什么至少没有关于 Callback 声明参数和分配的 lambda 之间差异的警告。 (const int &amp;numconst int num

当不使用const 时,它不会编译。

PS。如果您找到更好的标题,请随时编辑。

【问题讨论】:

  • 这种差异int 在 lambda 上是故意的吗?如果是,您应该在问题中提及这一点。当我第一次阅读它时,我忽略了那个细节
  • @idclev463035818 这正是问题所在
  • std 函数采用非引用参数参数使用`std::function` 代替,它将起作用
  • 另外,在问题中更清楚地说明将避免告诉您修复回调类型的 cmets ;) 据我了解,您在问这是否是正确的行为(而不是如何修复代码)
  • 您可以将std::function&lt;void(const int)&gt; 替换为std::function&lt;void(const char)&gt;,它仍然可以编译。 std::function 是一个用于类型擦除的类,所以只要调用一个签名与另一个签名是有意义的并且是合法的,它就可以工作。

标签: c++ lambda c++17


【解决方案1】:

这是因为testCall 是一个仿函数对象,它通过复制捕获其参数,然后在其上调用 lambda。

试试:

Callback f = [](const int &num) {
        std::cout << "callback: " << num << " - " << &num << std::endl;
};

int main() {
        int num = 999;
        std::cout << "callback: " << num << " - " << &num << std::endl;
        f(num);
        [](const int &num) {
                std::cout << "callback: " << num << " - " << &num << std::endl;
        }(num);
}

你会看到类似的东西:

callback: 999 - 0x7ffeed60a9bc
callback: 999 - 0x7ffeed60a994
callback: 999 - 0x7ffeed60a9bc    

这意味着callBack 本身不是函数,而是对函数的间接引用。而且类型没有问题……

对此的回答可能有助于您了解幕后发生的事情:How std::function works

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-25
    • 2023-03-20
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多