继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

std::thread arguments must be invocable after conversion to rvalues

呼如林
关注TA
已关注
手记 342
粉丝 101
获赞 363
C++11 标准库中的 std::thread 类

C++11 标准库中的 std::thread 类提供了一个用于创建和管理线程的封装。线程是多任务并行执行的一个实体,它可以使程序同时执行多个任务,从而提高程序的运行效率。

使用 std::thread 时需要注意的问题

在使用 std::thread 时,我们需要注意传递给它的参数必须能够被调用。这是因为在 C++11 之后,rvalue 可以被直接作为函数参数和返回值。

以一个简单的例子来说明:

#include <iostream>
#include <thread>

void print_hello() {
    std::cout << "Hello from thread!" << std::endl;
}

int main() {
    auto&& arg = print_hello;  // 将函数及其参数移动到左端
    std::thread t(arg);       // 创建线程并执行函数

    return 0;
}

在这个例子中,我们定义了一个名为 print_hello 的函数,它接受一个 void 类型的参数。在 main 函数中,我们将 print_hello 函数及其参数传递给 std::thread 构造函数。这里需要注意的是,arg 是一个 std::add_const_t<decltype(arg)> 类型的变量,表示将参数类型转换为常量类型,以确保在创建线程时不会丢失类型信息。

现在让我们来看一下这个代码在编译时会检查什么。在编译时,会检查 arg 是否可以被转换为 void* 类型,因为 std::thread 构造函数需要一个 void* 类型的参数来保存线程 ID。如果 arg 不能被转换为 void* 类型,那么编译器会报错。

为了满足这种需求,我们可以将 arg 包装在一个 std::function 对象中。这样,我们就可以将 arg 作为参数传递给 std::thread 构造函数了。

#include <functional>

void print_hello() {
    std::cout << "Hello from thread!" << std::endl;
}

int main() {
    auto&& arg = std::bind(print_hello, nullptr);  // 将函数及其参数绑定到左端
    std::thread t(arg);       // 创建线程并执行函数

    return 0;
}

在这个例子中,我们使用了 std::bind 函数将 print_hello 函数和它的参数绑定在一起,并将结果赋值给 arg。这样,我们就可以将 arg 作为 std::thread 构造函数的一个重要参数了。

使用 std::thread 时需要注意的问题

在使用 std::thread 时,我们需要注意传递给它的参数必须能够被调用。这是因为在 C++11 之后,rvalue 可以被直接作为函数参数和返回值。

以一个简单的例子来说明:

#include <iostream>
#include <thread>

void print_hello() {
    std::cout << "Hello from thread!" << std::endl;
}

int main() {
    auto&& arg = print_hello;  // 将函数及其参数移动到左端
    std::thread t(arg);       // 创建线程并执行函数

    return 0;
}

在这个例子中,我们定义了一个名为 print_hello 的函数,它接受一个 void 类型的参数。在 main 函数中,我们将 print_hello 函数及其参数传递给 std::thread 构造函数。这里需要注意的是,arg 是一个 std::add_const_t<decltype(arg)> 类型的变量,表示将参数类型转换为常量类型,以确保在创建线程时不会丢失类型信息。

现在让我们来看一下这个代码在编译时会检查什么。在编译时,会检查 arg 是否可以被转换为 void* 类型,因为 std::thread 构造函数需要一个 void* 类型的参数来保存线程 ID。如果 arg 不能

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP