使用成员函数创建std :: function无法编译

我遇到了C ++类的编译问题。

我的代码在这里:

#include <chrono>
#include <cstdint>
#include <thread>
#include <functional>

class Monitors {

public:

    Monitors(std::uint32_t timeout1,std::uint32_t timeout2) : timeout_1(timeout1),timeout_2(timeout2) {
        timer_start(task_1,timeout1); //does not compile
        timer_start(&Monitors::task_2,timeout2); //does not compile either

    }

private:

    void timer_start( std::function<void(void)>& func,std::uint32_t interval) {
        std::thread([func,interval]() {
            while (true) {
                func();
                std::this_thread::sleep_for(std::chrono::milliseconds(interval));                }
        }).detach();
    }

    void task_1() {
    }

    void task_2() {
    }


private:

    std::uint32_t timeout_1;
    std::uint32_t timeout_2;
};

错误是:

  

非const lvalue类型std :: function无法绑定到临时   输入void

出什么问题了?我该如何解决?

zhoujiang1984 回答:使用成员函数创建std :: function无法编译

编译器需要将成员函数转换为std::function<void()>对象以匹配timer_start函数参数列表。

该对象是一个临时对象,一旦完成对timer_start的调用,其生存期将结束。而且临时对象不能绑定到非常量引用(这就是错误消息的意思)。

简单的解决方案是改为通过值传递函数

void timer_start( std::function<void(void)> func,uint32_t interval)

第二个问题是,对于成员函数,您始终需要使用address-of运算符获取指向它的指针。而且,您始终还需要指定类。

这意味着您需要做

timer_start(&Monitors::task_1,timeout1);
timer_start(&Monitors::task_2,timeout2);

最后一个问题:非静态成员函数很特殊,因为它们需要调用一个对象。该对象就是函数内部的this指针。

调用该函数的对象通常作为隐藏的第一个参数传递,但是在使用例如std::function我们需要明确指定该参数。

因此最终声明必须为

void timer_start( std::function<void(Monitors*)> func,uint32_t interval)

这最后一件事还意味着您需要将指向对象的指针传递给函数,在这种情况下,您可以传递this

// Capture this
//           vvvv
std::thread([this,func,interval]() {
    while (true) {
        auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
        func(this);
        //   ^^^^
        // Pass this as argument
        std::this_thread::sleep_until(x);
    }
}).detach();
本文链接:https://www.f2er.com/3144157.html

大家都在问