C++11向线程函数传递参数

本文介绍了C++11中std::thread构造函数传递参数的相关知识。默认按值复制传递,若传递引用需用std::ref或std::cref包装。还分别阐述了普通函数和类成员函数作为线程函数时参数传递的方式及注意事项,最后给出使用建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

这个是std::thread构造函数之一,其中f是可调用对象,args是传递给f的参数。
默认传递给f的是按值复制,若需要传递引用参数给线程函数,则必须包装它(例如用 std::ref 或 std::cref )。

f类型:

  1. 普通函数
  2. 类成员函数

args分类:

  1. 引用传递
  2. 按值传递

普通函数

普通函数的示例如下

//按值传递
void FunbyCopy(int num)
{
    ++num;
}
//引用传递
void FunbyRef(int & num)
{
    ++num;
}
//测试代码
int num = 10;
//按值传递
std::thread   task1(FunbyCopy, num);
std::cout << "num is " << num << std::endl;

//没有用ref包装,被认为是按值传参数,而FunbyRef却是接受引用的参数,编译器会报错
//std::thread   task2(FunbyRef, num);
//std::cout << "num is " << num << std::endl;

//引用传递
std::thread   task3(FunbyRef, std::ref(num));
std::cout << "num is " << num << std::endl;

task1.join();
task2.join();
task3.join();

运行结果:

num is 10
num is 11

需要说明的是:task2没有用ref包装,被认为是按值传参数,而FunbyRef却是接受引用的参数,编译器会报错 

类成员函数指针

f可以传递一个成员函数指针作为线程函数,并提供一个合适的对象指针,之后传递的是线程函数的参数。参数形式可以是引用或者按值传递。

具体使用如下:

//测试类
class CMath
{
public:
    CMath(int _a, int _b) :a(_a), b(_b){}
    CMath(){}
    ~CMath(){}

    void add_sum(){sum = a + b;}
    
    int get_sum(){return sum;}

    void set_a(int _a){ a = _a;}
    
    void set_b(int _b){ b = _b;}
    
private:
    int a;
    int b;
    int sum;
};

 测试代码:

CMath math;
//设置值
math.set_a(20);
math.set_b(20);

//启动线程计算值
//构造函数的第一个参数是类成员指针,第二个参数是类对象指针
//如果需要给成员指针传递参数,则从第三个参数开始
std::thread  cal_task(&CMath::add_sum, &math);

//等待计算结束
cal_task.join();
//输出结果
std::cout << "sum is " << math.get_sum() << std::endl;

运行结果:

sum is 40

注意:对于类成员函数作为线程执行函数时,第一个参数必须是该成员函数所在类的一个对象,否则编译会报错,这是因为:第一个参数是  的成员函数的地址,没有经过实例化,所以不是内存中真正的位置,需要配合实例化后的对象的地址才可以一起使用。 

总结

使用类成员函数指针作为线程函数,是以面向对象的方式进行编码,在复杂类中使用成员函数指针可能会比较方便。如果是简单的逻辑,使用普通函数的形式就可了。

本文转自:

C++11向线程函数传递参数_Keep Moving~-优快云博客_c++ 线程传递参数

<think>好的,我现在需要帮助用户解决如何在C++中向线程所在函数传递多个参数的问题。首先,我应该回忆一下C++线程的基本用法,特别是std::thread的相关知识。 用户的问题是关于传递多个参数,所以我要先确定std::thread创建线程时如何传递参数。记得std::thread的构造函数会将参数传递函数参数是按值传递的,如果需要传递引用,必须使用std::ref或者std::cref。 接下来,用户可能需要一个具体的例子来说明如何传递多个参数。我应该举一个简单的例子,比如一个函数接受多个不同类型的参数,比如int、string和double,然后在创建线程的时候传递这些参数。 需要注意的是,如果函数参数是引用类型,必须用std::ref来包装,否则会导致编译错误或者未定义行为。例如,如果函数是void func(int a, std::string& s, double d),那么在传递字符串参数的时候,需要使用std::ref(s)。 另外,C++11之后的可变参数模板支持传递多个参数,所以用户只需要按顺序列出参数即可。但要注意参数的生存期,确保线程执行时参数仍然有效,尤其是当参数是指针或引用时。 可能还需要提到使用lambda表达式或者绑定器(std::bind)来传递参数,但用户的问题可能更关注直接传递的方式,所以先重点说明std::thread的基本用法。 还需要检查一下是否有常见的错误,比如参数数量不匹配,或者类型转换问题,比如无法将传入的参数转换为函数所需的类型,这时候编译器会报错,用户需要注意错误信息。 最后,总结一下步骤:定义函数,创建std::thread对象,按顺序传递参数,处理引用的情况,确保参数的有效性。可能还需要提醒用户线程的join或detach操作。 现在组织这些思路,给出一个结构清晰的回答,包含示例代码和注意事项,确保用户能够理解并正确应用。</think>在C++中,通过`std::thread`向线程函数传递多个参数时,需遵循以下步骤: --- ### 1. **基本参数传递** 直接按参数顺序传递给`std::thread`构造函数参数会按值复制到线程内部存储。 **示例**: ```cpp #include <iostream> #include <thread> #include <string> // 定义接受多个参数函数 void printValues(int a, const std::string& s, double d) { std::cout << "a=" << a << ", s=" << s << ", d=" << d << std::endl; } int main() { int num = 42; std::string text = "Hello"; double value = 3.14; // 创建线程传递参数 std::thread t(printValues, num, text, value); t.join(); return 0; } ``` --- ### 2. **传递引用参数** 若需传递引用,必须使用`std::ref`或`std::cref`显式包装,否则会触发拷贝行为。 **示例**: ```cpp void modifyValue(int& x) { x *= 2; } int main() { int value = 10; std::thread t(modifyValue, std::ref(value)); // 传递引用 t.join(); std::cout << "Modified value: " << value << std::endl; // 输出20 return 0; } ``` --- ### 3. **传递对象指针** 可直接传递指针,但需确保对象生命周期覆盖线程执行过程。 **示例**: ```cpp void processData(const std::string* data) { std::cout << "Data: " << *data << std::endl; } int main() { std::string data = "Example"; std::thread t(processData, &data); // 传递指针 t.join(); return 0; } ``` --- ### 4. **使用Lambda表达式(复杂场景)** 若参数需动态生成或存在依赖关系,可用Lambda表达式捕获参数。 **示例**: ```cpp int main() { int a = 5, b = 7; std::thread t([a, b]() { // 捕获局部变量 std::cout << "Sum: " << (a + b) << std::endl; }); t.join(); return 0; } ``` --- ### **注意事项** 1. **参数生命周期**:确保传递参数线程执行期间有效(避免悬垂指针/引用)。 2. **参数顺序**:参数顺序必须与函数声明一致。 3. **性能优化**:传递大型对象时,优先使用`const引用`或`移动语义`(如`std::move`)。 --- ### 总结 通过`std::thread`构造函数直接传递参数,按顺序对应目标函数参数列表。若需传递引用,必须使用`std::ref`,传递指针时需自行管理对象生命周期。对于复杂场景,可结合Lambda表达式灵活处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值