C++ lambda,没有看到函数和参数?

C++ lambda, not seeing function and argument?

我有一些代码在 std::thread 周围使用包装器 class,它使用定时器结构(基于 boost::asio),每 5000 毫秒调用一次 methodToCallEachIteration() :

class OurThreadWrapperClass{
    OurThreadWrapperClass(boost::asio::io_service& = generic_timer_queue_s());
};

class A {
    A() : thread1(_TimerIOService){
        thread1.setInterval(5000);
        // This sets the callback function, to be called every INTERVAL ms.
        thread1.start([this](OurThreadWrapperClass&) {
            this->methodToCallEachIteration();
        });
    }

    void callAFunctionHere(std::bitset<10> arg) {
        // ...
    }

    void methodToCallEachIteration() {
        // ...
    }

    struct TimerService {
        constexpr static const size_t num_threads{2};

        TimerService(){
            for(auto& t: _threads){
                t = std::thread([this](){
                    boost::asio::io_service::work keepalive{_ioservice};

                    callAFunctionHere(_anArgument);  // The method and arg not recognised

                    (void)keepalive;
                    _ioservice.run();
                });
            }
        }

        operator boost::asio::io_service&() {
            return _ioservice;
        }

        boost::asio::io_service _ioservice{num_threads};
        std::thread _threads[num_threads];
    };

    OurThreadWrapperClass thread1;
    TimerService _TimerIOService;
    std::bitset<10> _anArgument;
};

我遇到的问题是我想从准备线程的 TimerService 中调用 callAFunctionHere()。我不能在 TimerService 中移动这个函数。但是,编译器抱怨找不到 callAFunctionHere()_anArgument:

error: cannot call member function callAFunctionHere(std::bitset<10>) without object

error: 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = TimerService::TimerService()::__lambda19; _Args = {}]', declared using local type TimerService::TimerService()::__lambda19', is used but never defined [-fpermissive]
       thread(_Callable&& __f, _Args&&... __args)

我想我需要更改 A::A() 中的 lambda,以便编译器可以 "see" 方法和参数,但我不太确定如何?

在调用 callAFunctionHere 的 lambda 中,捕获的 thisclass A::TimerService 的实例,但您试图隐式使用 class A实例。您需要引用类型为 A 的对象,并使用该对象的成员。

class A {
    A() : _TimerIOService(this), thread1(_TimerIOService){
        //...
    }
    //...
    struct TimerService {
        A *a_;
        constexpr static const size_t num_threads{2};

        TimerService(A *a) : a_(a) {
            //...
    //...
    TimerService _TimerIOService;
    OurThreadWrapperClass thread1;
    std::bitset<10> _anArgument;
};

注意 _TimerIOService 需要排在 thread1 之前。 现在,A::TimerService 中的 lambda 使用 a_ 访问所需的成员。

一如既往,将问题分解为 MVCE:

class A {
    void callAFunctionHere() {}

    struct TimerService {
        TimerService() {
            callAFunctionHere();
        }
    };
};

int main()
{
    A a;
    A::TimerService ts;
}

http://ideone.com/lEUCvO

prog.cpp: In constructor 'A::TimerService::TimerService()':
prog.cpp:6:35: error: cannot call member function 'void A::callAFunctionHere()' without object
             callAFunctionHere();

此特定错误告诉您,由于名称解析,编译器可以判断您正在尝试访问外部作用域 (class A) 的 function/member,但是您重新从内部 (class A::TimerService).

实例 的上下文中进行操作

这行代码:

 callAFunctionHere(_anArgument);

写在A::TimerService::TimerService()里面,所以this指针是(A::TimerService*) this,代码展开为:

 A::callAFunctionHere(A::_anArgument);

this 不能应用于其中任何一个,因为 AA::TimerService.

之间没有直接继承或转换

classes 嵌套是为了 命名目的,就像 namespace,但它们在其他方面是离散的:只是因为 TimerService 是在 A 内部声明不会在名称范围之外连接它们的实例:它不会建立继承或转换关系

也许您想要做的是创建一个通用的 TimerService class,它可以通过继承来描述可重用的功能:

#include <iostream>

struct TimerService
{
    virtual void handleTimerEvent() = 0;

    TimerService()
    {
    }

    void trigger()
    {
        handleTimerEvent();
    }
};

class A : public TimerService
{

    const char* m_name;

public:
    A(const char* name_) : TimerService(), m_name(name_) {}

    void handleTimerEvent() override
    {
        std::cout << "Handling timer event in " << m_name << '\n';
    }
};

void triggerEvent(TimerService& service)
{
    service.trigger();
}

int main()
{
    A a("A instance 'a'"), b("A instance 'b'");
    triggerEvent(b);
    triggerEvent(a);
}

http://ideone.com/92aszw