如何为lambda分配重载operator =? [英] How can I overload operator= for lambda assignments?
问题描述
我正在尝试将一个函数插入到映射中,但我想先检查一下,所以我想重载std :: function的赋值操作,这可能吗?
我尝试重载赋值操作,因此,如果分配了预期以外的内容,则赋值运算符函数应将其包装在预期函数中并返回.
I am trying to insert a function into a map but I want to check it first so I would like to overload assignment operation for std::function, is this possible?
I try to overload the assignment operation, so if something other than expected is assigned, the assignment operator function should wrap it in the expected function and return it.
#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; };
^
推荐答案
听起来像您需要的是代理类.问题是,当您从on()
返回std::function<..>&
时,最终会得到std::function
.您不能覆盖该类的operator=
,这是我认为您正在尝试做的.相反,您要覆盖MyClass::operator=
-这是您从未真正调用过的函数.
Sounds like what you need is a proxy class. The problem is, when you return a std::function<..>&
from on()
, you end up with a std::function
. You can't overwrite that class's operator=
, which is what I think you're trying to do. Instead, you're overwriting MyClass::operator=
- which is a function you're never actually calling.
相反,返回一个您可以控制的代理.像这样:
Instead, return a proxy whose assignment you can control. Something like this:
struct Proxy {
std::function<void(int, int)>& f;
};
Proxy on(int type, int id){ return {events[type][id]}; };
然后我们可以为Proxy::operator=
提供特殊的重载. 有效,正确的类型"情况:
And then we can provide special overloads for Proxy::operator=
. The "valid, correct type" case:
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;
}
有了它,您原来的main()
将会编译并执行您期望的操作.
With that, your original main()
will compile and do what you expect.
这篇关于如何为lambda分配重载operator =?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!