这是我的问题:
我有一个包含容器成员的课程,例如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 version 8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04)
与-std=c++17
一起使用
答案 0 :(得分:1)
函数parallelStuff
希望获得 const迭代器,而您必须提供它们。
您可以获得 const迭代器:
cbegin
/ cend
或
begin
/ end
在下面的行
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
返回了与{{1 }}声明。