相关疑难解决方法(0)

如何从移动捕获lambda表达式创建一个std :: function?

我正在尝试创建std::function一个移动捕获lambda表达式.请注意,我可以创建一个移动捕获lambda表达式而不会出现问题; 只有当我尝试将其包装成一个std::function我得到错误时.

例如:

auto pi = std::make_unique<int>(0);

// no problems here!
auto foo = [q = std::move(pi)] {
    *q = 5;
    std::cout << *q << std::endl;
};

// All of the attempts below yield:
// "Call to implicitly-deleted copy constructor of '<lambda...."

std::function<void()> bar = foo;
std::function<void()> bar{foo};
std::function<void()> bar{std::move(foo)};
std::function<void()> bar = std::move(foo);
std::function<void()> bar{std::forward<std::function<void()>>(foo)};
std::function<void()> bar = std::forward<std::function<void()>>(foo);
Run Code Online (Sandbox Code Playgroud)

我会解释为什么我要写这样的东西.我写了一个UI库,类似于jQuery的或JavaFX的,允许用户通过传递给处理鼠标/键盘事件std::functions到方法有相似的名字on_mouse_down(),on_mouse_drag(),push_undo_action(),等.

显然,std::function我想要传入的理想情况下应该使用移动捕获lambda表达式,否则我需要求助于我在C++ 11作为标准时使用的丑陋的"release/acquire-in-lambda"习语:

std::function<void()> baz = …
Run Code Online (Sandbox Code Playgroud)

c++ lambda std c++14

52
推荐指数
3
解决办法
7066
查看次数

移动lambda:一旦你移动捕获了一个只移动的类型,lambda如何被使用?

这个答案解释了如何在C++ 14中移动捕获lambda中的变量.

但是,一旦你std::unique_ptr在lambda中移动捕获了一个不可复制的对象(例如a ),就无法复制lambda本身.

如果你可以移动 lambda,那就没问题,但是在尝试这样做时我遇到了编译错误:

using namespace std;

class HasCallback
{
  public:
    void setCallback(std::function<void(void)>&& f)
    {
      callback = move(f);
    }

    std::function<void(void)> callback;
};

int main()
{
  auto uniq = make_unique<std::string>("Blah blah blah");
  HasCallback hc;
  hc.setCallback(
      [uniq = move(uniq)](void)
      {
        std::cout << *uniq << std::endl;
      });

  hc.callback();
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下错误g++(我试图只复制相关的行):

error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&’
Run Code Online (Sandbox Code Playgroud)

......我想,我暗示我移动lambda的尝试失败了.

clang++ 给出了类似的错误.

我试着明确地move使用lambda(即使它是一个临时值),但这没有帮助.

编辑:下面的答案充分解决了上述代码产生的编译错误.对于另一种方法,简单地release将唯一的指针的目标值成std::shared_ptr,它可以被复制.(我不是写这个作为答案,因为这会假设这是一个XY问题,但是为什么unique_ptr不能在被转换为a的lambda中使用的根本原因std::function很重要.) …

c++ lambda move c++14

19
推荐指数
2
解决办法
6727
查看次数

在lambda C++中捕获std :: promise 14

我想创建一个状态机,它在自己的线程中处理提交的信号.我使用Visual Studio 2015,因此支持C++ 11和部分C++ 14.信号存储在容器中.每个信号表示为std :: function.我想从客户端等待,直到状态机处理提交的信号,因此它是一种同步信号.

我的问题是:我无法将std :: promise捕获到lambda中并将其添加到容器中.

#include <functional>
#include <future>
#include <list>

std::list<std::function<int()>> callbacks;

void addToCallbacks(std::function<int()>&& callback)
{
    callbacks.push_back(std::move(callback));
}

int main()
{
    std::promise<int> prom;
    auto fut = prom.get_future();

    // I have made the lambda mutable, so that the promise is not const, so that I can call the set_value
    auto callback = [proms{ std::move(prom) }]() mutable { proms.set_value(5); return 5; };

    // This does not compile
    addToCallbacks(std::move(callback));

    // This does not compile either, however this …
Run Code Online (Sandbox Code Playgroud)

c++ lambda promise c++11 c++14

11
推荐指数
2
解决办法
3995
查看次数

捕获参数是从右值 lambda 复制的?

在将 lambda 转换为 的过程中是否复制了捕获的参数std::function
我需要将捕获不可复制类型的 lambda 转换为std::function.
所以我将一个 lambdastd::function作为右值传递给,但发生了错误。

// Foo is non-copyable.
auto a = [f = Foo()]{ };
std::function<void()> b = std::move(a) // error, calls deleted Foo::Foo(const Foo&);
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11 std-function

8
推荐指数
1
解决办法
109
查看次数

我应该如何正确地将 packaged_task 移至 lambda?

我一直在尝试将 packaged_task 捕获到 lambda 中,但失败了。
\n我完全理解动作语义,也读过一些现代文学,我想我没有错过任何东西。我还阅读了 Josuttis 的移动语义书,以及关于广义 lambda 捕获的 ISO 主题以及ISO C++ 14 语言扩展
中的类似案例\n我有下一个代码:

\n\n
#include <thread>\n#include <vector>\n#include <functional>\n#include <queue>\n#include <condition_variable>\n#include <mutex>\n#include <future>\n#include <type_traits>\n#include <iostream>\n\n// #include\'s for below code and other purposes\n\nint main() {\n    auto f = []() { return 1; }; \n    std::queue<std::function<void()>> q;\n    std::packaged_task<int()> pack(f);\n    q.emplace([p = std::move(pack)] () mutable { p(); });\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里我创建了简单的函数队列,保存一些“void()”和packaged_task,传递“int”返回类型的“f”。
\n然后我尝试将 packaged_task 移动到 lambda 中以便稍后在其他线程中使用它(我需要在其他线程中使用它,这将在稍后执行它,当“pack”将被销毁时,这就是为什么我不能引用它)
\n看起来一切都很好,但是当我用“g++ main.cpp -o main -std=c++14”(甚至使用c++17)编译它时, g++ 告诉我这个:

\n\n
\n

/usr/include/c++/9/bits/std_function.h:176:6: 错误:使用已删除的函数 \xe2\x80\x98main()::::(const main()::&)\xe2\x80 …

c++ lambda move-semantics packaged-task

6
推荐指数
1
解决办法
1120
查看次数

为什么std :: function的初始化程序必须是CopyConstructible?

根据http://en.cppreference.com/w/cpp/utility/functional/function/function,初始化程序的类型,即F形式(5),应满足CopyConstructible的要求.我不太懂.为什么F只是MoveConstructible不行?

c++ templates constructor function c++11

5
推荐指数
1
解决办法
523
查看次数

为什么lambda对象中的局部变量是const?

以下代码无法编译.因为pt有类型const std::packaged_task<void()>>operator()不是const.

auto packagedTask = std::packaged_task<void()>>([]{});
auto future = packagedTask.get_future();
auto function = [pt = std::move(packagedTask)]{ (*pt)(); });
Run Code Online (Sandbox Code Playgroud)

这是解决方法:

auto packagedTask = std::make_shared<std::packaged_task<void()>>([]{});
auto future = packagedTask->get_future();
auto function = [pt = std::move(packagedTask)]{ (*pt)(); });
Run Code Online (Sandbox Code Playgroud)

为什么lambda对象中的局部变量是const?我想让第一个代码工作,而不需要管理工作量的开销.解决问题的最佳做法是什么?

c++ lambda c++14

3
推荐指数
1
解决办法
270
查看次数

我可以让返回类型自动处理具有相同签名但不同捕获的lambda吗?

我正在尝试使用auto作为返回的lambda函数的返回类型。这是一个最小的示例,它演示了我遇到的一个问题:

#include <iostream>
#include <memory>

auto
get_func()
{
    auto i = std::make_unique<int>(2);
    if (*i == 1) {
        return [i=std::move(i)]() {
            return *i;
        };
    }
    return [](){ return 2; };
}

int
main(int argc, char* argv[])
{
    auto func = get_func();
    std::cout << "val: " << func() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的Mac上,出现以下编译错误:

$ g++ -g -Wall -Werror -std=c++17 test.cc -o test
test.cc:13:5: error: 'auto' in return type deduced as '(lambda at test.cc:13:12)' here but deduced as '(lambda at test.cc:9:16)' in …
Run Code Online (Sandbox Code Playgroud)

c++ lambda auto c++17

2
推荐指数
1
解决办法
73
查看次数

C++ `std::move` 自定义类型转换为 lambda 捕获

我有一个类,其中删除了复制赋值运算符和复制构造函数,只留下了移动赋值运算符和移动构造函数。例如:

struct Number {
  public:
  int *pNum;

  Number &operator=(const Number &rhs) = delete;
  Number(const Number &rhs) = delete;

  Number &operator=(Number &&rhs) {
    if (&rhs == this) {
      return *this;
    }

    pNum = rhs.pNum;
    rhs.pNum = nullptr;
    return *this;
  }

  Number() = default;

  Number(Number &&rhs) {
    *this = std::move(rhs);
  }

  ~Number() {
    delete pNum;
  }
};
Run Code Online (Sandbox Code Playgroud)

现在,我想使用std::move将这个类捕获到一个 lambda 中。例如:

int main() {
  std::function<int(int)> add;


  int a = 3;

  {

    Number n{};
    n.pNum = new int;
    *n.pNum = 5;

    add …
Run Code Online (Sandbox Code Playgroud)

c++ lambda

0
推荐指数
2
解决办法
104
查看次数