使用线程可变参数模板约束时发生错误

时间:2015-09-21 14:39:11

标签: multithreading c++11 variadic-templates

void f(vector<int>& v){
    for(const auto& x:v) cout << x;
}

class F{
private:
    vector<int> v;
public:
    F(vector<int>& vc):v{vc}{}
    void operator()(){
        for(const auto& x:v) cout << x;
    }
};

int main()
{
    vector<int> some_vec{3,5,77,32,1};
    vector<int> vec{66,8,90,45,777};
    thread t1{f,some_vec};
    thread t2{F(vec)};
    t1.join();
    t2.join();
    cout << '\n';
}

错误&#34;没有名为&#39; type&#39; in&#39; class std :: result_of&lt; void(*(std :: vector))(std :: vector&amp;)&gt;&#39;发生

如果f中的参数向量声明为constvoid f(const vector<int>& v),则错误消失。

另一方面,具有函数对象F的代码可以正常工作。

Bjarne Stroustrup的代码 - C ++编程语言5.3.2传递参数

1 个答案:

答案 0 :(得分:1)

std::thread存储传递给其构造函数的参数的副本,然后使用这些副本的rvalues作为处理程序的参数。也就是说,函数f不能使用std::vector的右值调用,因为它需要非const左值引用。即使你将它改为const左值引用,它也是实际传递给t1构造函数的副本。

相反,类F有一个隐式定义的复制构造函数,其函数调用操作符不需要参数,因此不会出现错误。 (并且F本身是在传递给线程的构造函数之前构造的。

如果你想让函数fsome_vec实例上运行,你必须用参考包装器包装它:

#include <functional>

std::thread t1{f, std::ref(some_vec)};
//                ~~~~~~~^