MSVC中能否将std::barrier作为成员变量并调用成员函数完成回调?
在MSVC中使用std::barrier成员变量调用成员函数
问题场景
以下代码在GCC中可正常编译运行,但在MSVC中编译失败:
#include <barrier> #include <functional> #include <iostream> struct Class { Class() : barrier(1, [this]() { onCompletion(); }) { barrier.arrive_and_wait(); } void onCompletion() { std::cout << "Completed." << std::endl; } std::barrier<std::function<void()>> barrier; }; int main() { Class(); }
核心需求是:在MSVC环境下,将std::barrier作为类成员变量,使其完成回调函数能够调用类的成员函数。
问题原因
MSVC对std::barrier的实现会严格检查对象初始化顺序——成员变量barrier在构造函数初始化列表中初始化时,this指向的对象尚未完全构造完成,编译器的诊断机制会因此报错。
可行解决方案
方案1:延迟初始化barrier
使用std::unique_ptr间接持有barrier,在构造函数体内完成初始化,此时对象已完成基础构造,this的使用是安全的:
#include <barrier> #include <functional> #include <iostream> #include <memory> struct Class { Class() { barrier = std::make_unique<std::barrier<std::function<void()>>>( 1, [this]() { onCompletion(); } ); barrier->arrive_and_wait(); } void onCompletion() { std::cout << "Completed." << std::endl; } std::unique_ptr<std::barrier<std::function<void()>>> barrier; }; int main() { Class(); }
方案2:静态成员函数+显式传递对象指针
将回调逻辑改为静态成员函数,显式传递对象指针,避免直接在初始化阶段捕获this:
#include <barrier> #include <functional> #include <iostream> struct Class { Class() : barrier(1, [this](std::barrier<>*) { onCompletionStatic(this); }) { barrier.arrive_and_wait(); } static void onCompletionStatic(Class* self) { self->onCompletion(); } void onCompletion() { std::cout << "Completed." << std::endl; } std::barrier<> barrier; }; int main() { Class(); }
结论
MSVC中完全可以实现std::barrier作为成员变量并调用成员函数,只需规避对象初始化阶段this的有效性问题,上述两种方案均可解决编译问题。
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

