c++ - Lambda 成员函数

标签 c++ c++11 lambda

我正在尝试在类中创建一个功能字段,用户可以将其设置为任意 lambda 函数,然后将其作为成员函数进行调用。该字段基本上是一个 std::function,但在调用其 operator() 时应隐式传递 this 作为其第一个参数。

假设 Event 类做了我想要实现的事情:

template <typename... Args> class Event;

然后我希望能够写:

class Container {
public:
    Event<int> func = this ;
};

int main() {
     Container c;
     c.func = [](Container* This, int x) {
         .......
     };
     c.func(42);
     return 0;
}

我希望能够像 std::function 那样分配其他类似函数的对象(例如带有 operator() 的结构)。

我认为如果我将 Event 实现为 std::function 的派生物,并导入它的 operator= 定义,它就会起作用.但似乎有些歧义。

这是我写的:

#include <functional>

class Container;

template <typename... Args>
class Event : public std::function<void(Container*, Args...)> {
private:
    typedef std::function<void(Container*, Args...)> ParentType;
    Container* This;
public:
    using ParentType::operator=;

    Event(Container* This) : This(This) {}
    void operator()(Args... args) {
        ParentType::operator()(This, args...);
    }
};

不幸的是,我在尝试编译它时收到一些警告和错误:

event.h(17): warning C4522: 'Event<int>' : multiple assignment operators specified
1>          container.h(6) : see reference to class template instantiation 'Event<int>' being compiled
1>main.cpp(19): error C2666: 'std::function<void (Container *,int)>::operator =' : 3 overloads have similar conversions
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(632): could be 'std::function<void (Container *,int)> &std::function<void (Container *,int)>::operator =(const std::function<void (Container *,int)> &)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(642): or       'std::function<void (Container *,int)> &std::function<void (Container *,int)>::operator =(std::function<void (Container *,int)> &)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(674): or       'std::function<void (Container *,int)> &std::function<void (Container *,int)>::operator =(std::function<void (Container *,int)> &&)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(700): or       'std::function<void (Container *,int)> &std::function<void (Container *,int)>::operator =(std::nullptr_t)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(685): or       'std::function<void (Container *,int)> &std::function<void (Container *,int)>::operator =<main::<lambda_744a2f58777db28ba36902fcfe375a8a>>(_Fx &&)'
1>          with
1>          [
1>              _Fx=main::<lambda_744a2f58777db28ba36902fcfe375a8a>
1>          ]
1>          while trying to match the argument list '(Event<int>, main::<lambda_744a2f58777db28ba36902fcfe375a8a>)'

...我迷路了。 我应该只“导入”继承的 operator= 之一吗?实现我自己的并以某种方式调用其中之一?

最佳答案

调用父 operator= 对于多态对象来说是个糟糕的主意。请记住,function 是多态的。总的来说,我认为您应该更喜欢聚合而不是派生,因为那样您可以更好地控制调用什么以及何时调用,如下所示:

template <typename... Args>
class Event  {
public:
    typedef std::function<void( Container*, Args... )> ParentType;
    ParentType inner;
    Container* This;

    Event( Container* This ) : This( This ) {}
    void operator()( Args... args ) {
        inner( This, args... );
    }
};

int main() {
    Container c;
    c.func.inner = []( Container* This, int x ) {
    };
    c.func( 42 );
    return 0;
}

当然,如果您不想公开Event 的内部结构,您可以将它们设为私有(private)并提供适当的设置函数。

关于c++ - Lambda 成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22453980/

相关文章:

c++ - 右值总是不变的吗?

python - 如何在 IDE 中调试 Cython

c++ - C++数据流编程: Interconnecting Nodes With Differing Template Parameters

c++ - 匿名命名空间中的 constexpr 字符串文字?

c++ - 在元编程中强制执行不变量

Java:使用 lambda 而不将其分配给变量

c++ - 将值存储在指针 var 中

c++ - 整数类型的 std::swap 有多快?

python - 在 Python 中为 AWS Lambda 从字符串内容创建一个动态 zip 文件

lambda - (反射(reflection))隐式和显式 lambda 声明