std::thread 通过引用传递向量元素

Posted

技术标签:

【中文标题】std::thread 通过引用传递向量元素【英文标题】:std::thread pass vector element by reference 【发布时间】:2016-05-29 12:23:09 【问题描述】:

我试图弄清楚为什么以下工作:

threaded thr[8] =  threaded(), threaded() ,threaded() ,threaded() ,threaded() ,threaded() ,threaded() ,threaded() ;
std::vector<std::thread> vec;
for (int i = 0; i < threads; i++)

    vec.push_back(std::thread(&threaded::calc, &thr[i], i, num_samples));

以下不是:

std::vector<threaded> thr;
std::vector<std::thread> vec;
for (int i = 0; i < threads; i++)

    thr.push_back(threaded());
    vec.push_back(std::thread(&threaded::calc, &thr[i], i, num_samples));

我尝试使用 std::ref 而不是 & - 它仍然不起作用。这是线程的定义:

struct threaded

    float elapsed1 = 0;
    float elapsed2 = 0;
    float res = 0;
    float res_jit = 0;
    void calc(int thread, int num_samples)//do something
;

不起作用我的意思是,当我使用向量和 & 时,我遇到内存访问冲突,当我尝试使用 std::ref(thr[i]) 而不是 & 时,它不想编译出现以下错误:

Error   C2672   'std::invoke': no matching overloaded function found        

Error   C2893   Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'        

如果我只使用 thr[i] 它工作正常,但我想修改线程类的值,所以我真的不想传递副本。

【问题讨论】:

【参考方案1】:

随着向量thr 在每次调用push_back 时变大,最终超过保留内存区域的容量,它需要重新分配其存储空间并将其元素复制(或移动)到新分配的空间。一旦发生这种情况,对象就会开始存在于新的内存地址下,因此先前获得的地址将失效。为了防止重定位,在进入循环之前要预留足够的空间:

std::vector<threaded> thr;
thr.reserve(threads);

或默认一次性构造所有元素:

std::vector<threaded> thr(threads);

【讨论】:

以上是关于std::thread 通过引用传递向量元素的主要内容,如果未能解决你的问题,请参考以下文章

在 C++11 中通过引用 std::thread 传递对象

thread库,附带程序介绍

std::thread 按引用传递调用复制构造函数

值传递和引用传递的区别

如何访问在 C++ 中通过引用传递的列表/向量的元素

通过引用将向量对象传递给函数? [关闭]