c++ - 如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用失败
问题描述
这是我的问题:
我有一个带有容器成员的类,比如std::vector
. 我有一个函数,比如说parallelStuff
,它引用这个容器的迭代器并用它做一些事情。我想使用并行执行所述功能std::thread
我已经实现了这个,它工作正常。现在我想编写一个非常相似的设置,但有一点不同:在工作版本中,在调用线程的函数中parallelStuff
,我从对容器的引用中获取迭代器。
但是,如果我从非引用容器中获取迭代器,编译将失败。
这是一个复制问题的最小示例:
#include <thread>
#include <vector>
class Foo {
public:
Foo() {}
auto const & member() { return member_; }
void parallelStuff(std::vector<int>::const_iterator & it,
std::vector<int>::const_iterator const & end) {
// do stuff while it != end
}
private:
std::vector<int> member_;
};
int main(int argc, char * argv[]) {
auto foo = Foo();
auto& member = foo.member();
// auto member = foo.member(); <-- copy instead of reference, this fails!
auto it = member.begin();
auto end = member.end();
auto t = std::thread(&Foo::parallelStuff, &foo,
std::ref(it), std::ref(end));
t.join();
return 0;
}
如前所述,如果我使用副本member
而不是参考,我会收到错误消息
/usr/include/c++/8/thread:120:17: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
谷歌搜索错误消息只将我带到一个站点,该站点解释说我需要包装std::ref()
我已经做过的参考参数。
有谁知道这里出了什么问题,可以请解释一下(以及如何解决这个问题)?
非常感谢!
PS:我使用gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04)
with-std=c++17
解决方案
函数parallelStuff
期望获得const 迭代器,您必须提供它们。
您可以获得const 迭代器:
- 通过在对象上调用
cbegin
/cend
或者
- 通过调用
begin
/end
在const 对象上
在下面的行中
auto member = foo.member();
自动类型推导有效,它丢弃了初始化程序的引用性和常量性。所以member
只是声明为vector<int>
. 因此begin
/end
返回与 .vector<int>::iterator
的参数不匹配的内容parallelStuff
。
要在非常量对象上获取const 迭代器,只需调用cbegin
/ cend
:
auto it = member.cbegin();
auto end = member.cend();
这有效
auto& member
因为member
被推论为const vector<int>&
,所以begin
/end
调用 const 对象返回 const 迭代器 -vector<int>::const_iterator
与parallelStuff
声明匹配。
推荐阅读
- powershell - 在 PowerShell 中确定 OpenType 字体的确切名称
- swift - 我应该在 Swift 中使用 Array 还是 NSArray
- c# - 两个列表对象之间的随机交换
- php - 包含关联数组时如何从多维数组中获取唯一的数组?
- angular - 在 Ionic 中更改选项卡后地图冻结
- jquery - 通过 AJAX 传递多个选定的 div 值
- java - GridPane 与 ScrollPane 内的间隙呈现错误
- python - 如何使用python从用户时间线twitter检索/查找tweet上的特定文本
- hex - Roku:如何将 rgba 转换为十六进制?
- mapbox - mapbox-gl 超集群 getLeaves