这是我的问题:
我有一个包含容器成员的类,例如 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
谷歌搜索错误消息只会让我找到 site解释我需要在 std::ref()
中包装引用参数,我已经这样做了。
有人知道这里出了什么问题吗,请解释一下(以及如何解决这个问题)?
非常感谢!
PS:我使用 gcc 版本 8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04)
和 -std=c++17
最佳答案
函数parallelStuff
期望获得 const 迭代器,而您必须提供它们。
您可以获得常量迭代器:
- 调用
cbegin
/cend
在一个物体上
或
- 调用
begin
/end
在常量对象
在下面一行
auto member = foo.member();
自动类型推导 可以从初始化程序中丢弃引用性和常量性。所以member
刚刚声明为 vector<int>
.所以begin
/end
返回 vector<int>::iterator
与 parallelStuff
的参数不匹配的内容.
要在非 const 对象上获取 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
声明。
关于c++ - 如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56463053/