std ::在lambda捕获中移动const std :: vector [英] std::move a const std::vector in a lambda capture
问题描述
我正在尝试通过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_ptr
s.
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 const
ness 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屋!