std ::在lambda捕获中移动const std :: vector [英] std::move a const std::vector in a lambda capture

查看:102
本文介绍了std ::在lambda捕获中移动const std :: vector的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过lambda捕获将 std :: vector< std :: unique_ptr< some_type>> 传输到另一个线程.

I'm trying to transfer a std::vector<std::unique_ptr<some_type>> to a different thread, via a lambda capture.

由于我需要在函数超出范围时不清理向量,因此我需要按值(而不是按引用)使用它.

Since I need the vector to not be cleaned up when the function goes out of scope, I need to take it by value (and not by reference).

由于它是unique_ptrs的向量,因此我需要将其移动(而不是复制)到捕获中.

Since it's a vector of unique_ptrs, I need to move (and not copy) it into the capture.

我正在使用广义lambda捕获来移动捕捉时的向量.

I'm using a generalized lambda capture to move the vector while capturing.

auto create_vector(){
    std::vector<std::unique_ptr<int>> new_vector{};
    new_vector.push_back(std::make_unique<int>(5));
    return std::move(new_vector);
}

int main() {
    const auto vec_const = create_vector();

    [vec=std::move(vec_const)](){
        std::cout << "lambda, vec size: " << vec.size() << std::endl;
    }();
}

问题:

如果我使用的是 const 本地向量,则由于尝试复制 unique_ptr s而导致编译失败.但是,如果删除 const 限定符,则代码可以编译并运行良好.

Issue:

If I'm using a const local vector, compilation fails due to attempting to copy the unique_ptrs. However if I remove the const qualifier, the code compiles and runs well.

auto vec_const = create_vector();

问题:

这是什么原因?const是否会禁用向量的可移动性"?为什么?

Questions:

What's the reason for this? Does being const disable the "movability" of the vector? Why?

在这种情况下如何确保向量的恒定性?

How would I ensure the constness of a vector in such a scenario?

评论和答案提到不能从中移除const类型.听起来很合理,但是编译器错误未能明确说明.在这种情况下,我期望以下两件事之一:

The comments and answers mention that a const type can't be moved from. Sounds reasonable, however the the compiler errors fail to make it clear. In this case I would expect one of two things:

  • std :: move(vec_const)应该引发关于从const(将其广播到右值)的转换是不可能的错误.
  • 向量move-constructor告诉我它拒绝接受const rvalues.
  • The std::move(vec_const) should throw an error regarding moving from const (casting it to rvalue) being impossible.
  • The vector move-constructor telling me that it refuses to accept const rvalues.

为什么这些不发生?为什么相反,分配似乎只是尝试在向量中复制unique_ptrs(这是我希望从向量copy-constructor获得的结果)?

Why don't those happen? Why does instead the assignment seems to just try to copy the unique_ptrs inside the vector (which is what I'd expect from the vectors copy-constructor)?

推荐答案

移动是一种破坏性的操作:您从概念上更改了要移动的事物的内容.

Moving is a disruptive operation: you conceptually change the content of the thing you move from.

所以是的:不能(也应该)从const对象中移出const对象.那将改变原始对象,从而使其 const ness无效.

So yes: a const object can (and should) not be moved from. That would change the original object, which makes its constness void.

在这种情况下, vector 没有 vector(const vector&&),只有 vector(vector&&)(移动构造函数)和 vector(const vector&)(复制构造函数).

In this case, vector has no vector(const vector&&), only vector(vector &&) (move constructor) and vector(const vector &) (copy constructor).

重载解析只会将带有 const vector 参数的调用绑定到后者(不会违反const正确性),因此将导致复制内容.

Overload resolution will only bind a call with const vector argument to the latter (lest const-correctness would be violated), so this will result in copying the contents.

我同意:错误报告很糟糕.当您遇到 unique_ptr 的问题时,很难编写关于 vector 的错误报告.这就是为什么的全部尾部从....到... 所必需,从而消除了视图.

I agree: error reporting sucks. It's hard to engineer an error report about vector when you hit a problem with unique_ptr. That's why the whole tail of required from ...., required from ... obliterates the view.

从您的问题和代码中,我可以看出您没有完全掌握移动语义学的东西:

From your question, and your code, I can tell that you don't fully grasp the move semantics stuff:

  • 您不应该移入返回值;返回值已经是一个右值,所以没有意义.
  • std :: move 并不会真正移动任何东西,它仅更改您要从中移动"的变量的限定符,以便可以选择正确的接收者(使用绑定"规则)).接收功能实际上是更改原始对象的内容.
  • you shouldn't move into a return value; a return value is already an rvalue, so there's no point.
  • std::move does not really move anything, it only changes the qualifier of the variable you want to 'move from', so that the right receiver can be selected (using 'binding' rules). It is the receiving function that actually changes the contents of the original object.

这篇关于std ::在lambda捕获中移动const std :: vector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆