如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用将失败
Passing reference to iterator with std::thread fails if container is not a reference in calling function
这是我的问题:
我有一个带有容器成员的类,比如说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)
和-std=c++17
函数parallelStuff
希望获得常量迭代器,您必须提供它们。
你可以得到常量迭代器:
- 通过在对象上调用
cbegin
/cend
或
- 通过调用
begin
/end
在 const 对象上
在下面的行中
auto member = foo.member();
自动类型推导的工作原理是从初始值设定项中丢弃引用性和恒定性。所以member
只是被宣布为vector<int>
.因此,begin
/end
返回vector<int>::iterator
与parallelStuff
参数不匹配的内容。
要在非常量对象上获取常量迭代器,只需调用cbegin
/cend
:
auto it = member.cbegin();
auto end = member.cend();
现场演示
这行得通
auto& member
因为member
被推导为const vector<int>&
,所以在 const 对象上调用的begin
/end
返回 const 迭代器 -vector<int>::const_iterator
与parallelStuff
声明匹配。
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- std::thread 增加 DLL 引用计数,从而防止卸载 DLL
- 为什么我们不允许将纯引用参数传递给 std::thread,但允许传递原始指针?
- 如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用将失败
- 创建RSA_PrivateKey时对"std::thread::_State::~_State()"的未定义引用
- 将回调函数中对对象的引用传递给 std::thread
- 将基类的引用传递给 boost::thread 并在派生类中调用虚函数是否有效
- 错误 C2280:'std::thread::thread(const std::thread &)':尝试引用已删除的函数
- 在 Ubuntu 14.04 上使用 boost 编译:未定义对 'boost::thread::get_id() const' 的引用
- 我可以将数组每次移动引用传递给 std::thread 吗?
- 如何创建带有引用的函数指针的 std::thread
- std::thread constructor传递指针和通过引用传递有区别吗
- 未定义对在mingw64上使用boost.thread的InterlockedCompareExchange的引用(但不
- 通过引用C++11中的std::thread来传递对象
- 为什么我不能使用 std::thread 通过引用发送对象
- 未定义对`boost::thread的引用
- 为什么std::thread通过转发引用接受一个函子
- 获取对 std::thread::_M_start_thread 的未定义引用