【问题标题】:C++ Lambda: Access static method in lambda leads to error 'this was not captured for this lambda function'C++ Lambda:访问 lambda 中的静态方法会导致错误“这不是为此 lambda 函数捕获的”
【发布时间】:2013-10-22 10:02:54
【问题描述】:

考虑以下代码:

//this is what I want to call; I cannot modify its signature
void some_library_method(void(*fp)(void));

class Singleton{
    public:
        static Singleton *instance();
        void foo();
        void bar();
    private:
        Singleton();
};

void Singleton::foo(){
    //this leads to an error ('this' was not captured for this lambda function)
    void(*func_pointer)(void) = []{
        Singleton::instance()->bar();
    };
    some_library_method(func_pointer);
}

我想调用一个我无法修改的函数(参见some_library_methodabove),它需要一个函数指针作为参数。调用应在类成员foo() 中完成。我知道我不能在那里访问类成员,但我想做的就是以静态方式访问单例类(检索单例实例)。

有什么方法可以修改 lambda 表达式以显示目标编译器 g++ v4.7.2 确实不需要需要引用 this

【问题讨论】:

    标签: c++ gcc c++11 lambda


    【解决方案1】:

    以下变通方法有效:

    template< typename T > T* global_instance() { return T::instance(); }
    
    void(*func_pointer)(void) = []{
        global_instance<Singleton>()->bar();
    };
    

    【讨论】:

      【解决方案2】:

      您可以使用本地定义的常规函数​​来代替 lambda

      void Singleton::foo() {
          struct T {
              static void cb(){ Singleton::instance()->bar(); }
          };
          some_library_method(T::cb);
      }
      

      【讨论】:

      • T 似乎是该类型的糟糕名称选择。
      • @Yakk: IMO LocalStructureNeededBecauseCppDoesntAllowLocalFunctions 会更糟:-)
      • @muffel:不幸的是,本地结构不能与模板一起使用,因为我不理解标准中指定的显式限制,并且该限制存在于 C++03 中,并且也被 C 继承了 IIRC ++11。您仍然可以使用它们来声明本地回调,而不必将回调代码放置在远离用途且不会污染模块名称空间的地方。
      • 为什么哦,为什么 lambda 的语义与内联结构的语义有任何不同...
      • @Cuadue:lambdas(闭包)可以访问本地变量,这通常非常强大(只是碰巧在这种情况下不需要)。不幸的是,要真正体会到引用捕获闭包的全部功能,该语言需要为本地人提供基于垃圾收集的生命周期(不仅是基于堆栈的生命周期),但这对于 C++ 来说变化太大了。
      猜你喜欢
      • 2016-01-21
      • 2012-11-07
      • 2017-12-20
      • 2011-09-07
      • 1970-01-01
      • 2012-07-09
      • 2017-04-16
      • 1970-01-01
      相关资源
      最近更新 更多