如何为lambda赋值重载operator =?

时间:2015-09-17 20:08:13

标签: c++ function lambda operator-overloading

我正在尝试将一个函数插入到一个地图中,但我想先检查它,所以我想重载std :: function的赋值操作,这可能吗?

我尝试重载赋值操作,因此如果指定了除预期之外的其他内容,赋值运算符函数应将其包装在期望的函数中并返回它。

#include <iostream>
#include <map>
#include <functional>

class MyClass{
    public:
    std::map<int, std::map<int, std::function<void(int,int)>>> events;
    std::function<void(int,int)>& on(int type, int id){ return events[type][id]; };
    template<typename T> std::function<void(int,int)>& operator= (T&& fn){
        std::wcout << L"assigning correct function\n";
        return [&](int x, int y){
            if(typeid(fn)==typeid(std::function<void(int,std::wstring)>)) fn(x, L"two");
        };
    }
};

int main(int argc, char **argv)
{
    MyClass obj;
    obj.on(1,2) = [](int x, int y){ std::wcout << L"int " << x << L" " << y << std::endl; };  //this works but it's not calling the overload operator
    obj.on(1,2) = [](int x, std::wstring y){ std::wcout << L"string " << x << L" " << y << std::endl; }; //I need this to work too
    obj.events[1][2](2,3);
    return 0;
}

输出:

test.cpp:23:14: error: no match for 'operator=' (operand types are 'std::function<void(int, int)>' and 'main(int, char**)::<lambda(int, std::__cxx11::wstring)>')
obj.on(1,2) = [](int x, std::wstring y){ std::wcout << L"string " << x << L" " << y << std::endl; };
         ^

1 个答案:

答案 0 :(得分:2)

听起来你需要的是一个代理类。问题是,当您从PFQuery.query.findObjectsInBackgroundWithBlock返回std::function<..>&时,最终会得到on()。你不能覆盖那个类的std::function,这是我认为你想要做的。相反,你要覆盖operator= - 这是一个你从未真正打过电话的函数。

相反,请返回您可以控制其分配的代理。像这样:

MyClass::operator=

然后我们可以为struct Proxy { std::function<void(int, int)>& f; }; Proxy on(int type, int id){ return {events[type][id]}; }; 提供特殊的重载。 “有效,正确的类型”案例:

Proxy::operator=

template <typename F, std::enable_if_t<std::is_assignable<std::function<void(int, int)>&, F&&>::value>* = nullptr> Proxy& operator=(F&& func) { f = std::forward<F>(func); return *this; } 案例:

wstring

这样,您的原始template <typename F, std::enable_if_t<std::is_assignable<std::function<void(int, std::wstring)>&, F&&>::value>* = nullptr> Proxy& operator=(F&& func) { std::wcout << L"assigning correct function\n"; f = [func = std::forward<F>(func)](int x, int ) { func(x, L"two"); }; return *this; } 将编译并执行您期望的操作。