【问题标题】:Error with lambda in template member function模板成员函数中的 lambda 错误
【发布时间】:2020-06-11 20:19:46
【问题描述】:

我有以下 c++ 代码

#include <iostream>

template<typename Func>
class Foo
{
private:
    Func func;

public:
    Foo(Func func) : func(func) {}

    template<typename T>
    Func wrap()
    {
        Func clbk = func;
        auto wrapperCB = [clbk](T t) {
            auto job = [clbk, t](){
                clbk(t);
            };
            job();
        };

        return wrapperCB;
    }

    template<typename T>
    void call(T t)
    {
        func(t);
    }
};

int main()
{
  int m = 2;
  auto f = [](int & p) {std::cout << "test success " << p << "\n";};
  auto obj = std::make_shared<Foo<std::function<void(int &)>>>(f);
  auto wrapper = obj->template wrap<int &>();
  wrapper(m);
  return 0;
}

这是编译错误

tsavs-mbp:p utsagarw$ clear; g++ -std=c++11 a.cpp -o z; ./z
a.cpp:18:17: error: no matching function for call to object of type 'const std::__1::function<void (int &)>'
                clbk(t);
                ^~~~
a.cpp:38:32: note: in instantiation of function template specialization 'Foo<std::__1::function<void (int &)> >::wrap<int &>' requested here
  auto wrapper = obj->template wrap<int &>();
                               ^
/Applications/Xcode_10.1/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1677:9: note: candidate function not viable: 1st argument ('const int') would lose const qualifier
    _Rp operator()(_ArgTypes...) const;
        ^
1 error generated.

我不明白这个错误。这个 const 是从哪里来的?

如果在wrap 中我不创建job 函子并直接调用clbk,则它构建成功。这个jobtype T做了什么?

template<typename T>
Func wrap()
{
    Func clbk = func;
    auto wrapperCB = [clbk](T t) {
        clbk(t);
    };

    return wrapperCB;
}

【问题讨论】:

    标签: c++11 templates lambda compiler-errors constants


    【解决方案1】:

    如果您想修改 lambda 中的任何捕获变量,您必须将其指定为 mutable

    t变量被拷贝捕获,所以只能读取:

             auto job = [clbk, t]()  // <-- t passed by copy
             {
                 clbk(t);            // clbk takes t by reference -> int&
             };
    

    您的回调,clbk 具有签名 int&amp;,因此这意味着它可以修改 t。什么是不允许的。

    解决方案:

             auto job = [clbk, t]() mutable // keyword 'mutable' added
             {
                 clbk(t);  // clbk can change t
             };
    

    或使functionconst int&amp; 为参数 - 然后t 只能读取。

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多