【问题标题】:How do I pass an instance member function as callback to std::thread [duplicate]如何将实例成员函数作为回调传递给 std::thread [重复]
【发布时间】:2013-01-22 07:12:02
【问题描述】:

可能重复:
Start thread with member function

我对 C++ 非常陌生。我的经验主要是使用 javascript 和 java。

我在 Lion 上使用 Xcode。以下代码给了我一个编译错误“必须调用对非静态成员函数的引用;您的意思是不带参数调用它吗?”

class MyClass {
private:
    void handler() {
    }

public:
    void handleThings() {
        std::thread myThread(handler);
    }
};

我还尝试了this->handler&handler 和其他变体,但都没有奏效。这段代码可以编译并完成我想要的:

class MyClass {
private:
    void handler() {
    }

public:
    void handleThings() {
        std::thread myThread([this]() {
            handler();
        });
    }
};

为什么我不能传递对成员函数的引用?我的变通办法是最好的解决方案吗?

【问题讨论】:

  • 这不是“解决方法”...这是完成任务的正确方法(其中之一)。第二个是使用std::bind 而不是lambda。要调用类的方法,您必须提供该类的实例(this 指针作为任何非静态成员函数的第一个隐式参数)。仅将您要调用的方法的地址(没有实例)传递给std::thread ctor 显然是不够的。
  • 根据您的任务考虑使用std::async 而不是std::thread...,以防运行线程只是计算并退出(即不是偶数循环处理程序)
  • 我现在明白了。你的第一条评论 zaufi 以及这个答案 stackoverflow.com/a/12765270/711902 教会了我一些东西。

标签: c++ lambda function-pointers


【解决方案1】:
std::thread myThread(&MyClass::handler, this);
myThread.join();

【讨论】:

    【解决方案2】:

    在成员函数中使用lambda访问类成员,需要捕获this[this] 在下面的代码中是强制性的:

    void handleThings() 
    {
        std::thread myThread([this]() {
            handler();
        });
    }
    

    您可以通过引用捕获this,但它不如按值捕获它有效。因为通过引用需要双重间接(模编译器优化)

    void handleThings() {
            std::thread myThread([&]() {
                handler();
            });
        }
    

    Lambdas 通常是比bind 更好的选择。

    • 更易于读者理解。
    • 更高效。

    【讨论】:

    • this 只是一个指针,所以按值传递/捕获是相当好的......取决于编译器 this->handler() 中 C++11 支持的完整性,可能需要解决歧义。
    • 如何了解更多关于 lambda 与绑定性能的信息?这个答案stackoverflow.com/a/8884445/711902 似乎表明性能通常是相同的,至少对于 GCC 4.7?还是回答者在谈论其他事情?
    • 我还没有测试过,但是我读过 C++11 书籍,比如 Overview of the New C++ (C++0x) 提到的。
    • std::thread myThread(&MyClass::handler, this) 像竹子在stackoverflow.com/questions/10673585/… 中建议的怎么样?这和 std::bind 做同样的事情吗?这似乎是最干净的解决方案。
    • @TrevorDixon,是的,效果很好。它与bind 非常相似,并且在这种情况下做同样的事情,但并不总是完全相同,因为thread 处理其参数的方式不支持bind 支持的所有内容,请参阅stackoverflow.com/a/21066704/981959 了解一下更多细节
    【解决方案3】:

    如果你不想使用 lamda,可以使用std::mem_fun

    你能做到吗?

    std::thread myThread(std::mem_fun(&MyClass::handler),this);
    

    std::thread 接受函数的参数(这是第一个参数),this 作为参数传递给mem_fun 对象,然后该对象调用this 上的处理函数。

    您也可以很简单地执行以下操作,礼貌 - Start thread with member function

    std::thread myThread(&MyClass::handler,this);
    

    【讨论】:

    • 这里不需要 mem_fun。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 2015-04-12
    • 1970-01-01
    • 2016-03-13
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多