c++ - 如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用失败

标签 c++ multithreading reference stl iterator

这是我的问题:

我有一个包含容器成员的类,例如 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 迭代器,而您必须提供它们。

您可以获得常量迭代器:

  1. 调用cbegin/cend在一个物体上

  1. 调用begin/end常量对象

在下面一行

auto member = foo.member();

自动类型推导 可以从初始化程序中丢弃引用性和常量性。所以member刚刚声明为 vector<int> .所以begin/end返回 vector<int>::iteratorparallelStuff 的参数不匹配的内容.

要在非 const 对象上获取 const 迭代器,只需调用 cbegin/cend :

auto it = member.cbegin();
auto end = member.cend();

LIVE DEMO


这行得通

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/

相关文章:

java - 如何破坏 StringBuilder 线程安全(示例不安全代码很有可能被破坏)

c++ - 我应该使用静态工作池还是动态工作池(线程)?

c++ - 返回引用也会延长它的生命周期吗?

c++ - MPlab 8.83 IDE编译错误

c++ - 寻找用于自动构建和部署的脚本语言

c++数组打印十六进制?

c++ - MS Visual C++ 上的 xercesc 的 DOMNode "undefined"

java - HikariCP 和服务线程

c# - C# 教学引用

c# - 实在看不懂C#的引用