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 中,捕获的 this
是 class 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;
}
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
不能应用于其中任何一个,因为 A
和 A::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);
}
我有一些代码在 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 中,捕获的 this
是 class 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;
}
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
不能应用于其中任何一个,因为 A
和 A::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);
}