Wel*_*lls 3 c++ lambda templates delegates c++11
我正在尝试在C++中重新创建C#的委托类型的一些行为,并且我在编译时遇到了一个特定的错误 - 这里是相关的代码:
struct Nil { };
// Represents a C# Func
template <typename returnType = void,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil>
class Func
{
public:
vector<function<returnType(T1, T2, T3)>> _funcs;
void operator+=(returnType (*functionPointerToAdd)(T1))
{
auto myFunc = [&] ( returnType (*functionPointerToAdd)(T1) )
-> returnType (*)(T1, T2, T3)
{ functionPointerToAdd(T1); };
// add myFunc to the vector of functions...
}
};
Run Code Online (Sandbox Code Playgroud)
我想要做的是将一个函数指针包装在一个闭包中,该闭包的签名与该类的完整模板类型相匹配(有效地"丢弃"设置为'Nil'的值).我得到的错误是:
error C2275: 'T1' : illegal use of this type as an expression
Run Code Online (Sandbox Code Playgroud)
我正在使用MSVC10,我尝试按照在lambda失败的成员函数内访问类模板参数类型来定义模板变量,但无济于事.我意识到这个特定的实现存在一些问题,我将遇到这个问题,但除此之外,我只是好奇为什么我不能在lambda语句中使用类的模板参数.
我认为你仍然有一点点混乱的0x语法.
auto myFunc = [&] ( returnType (*functionPointerToAdd)(T1) ) -> returnType (*)(T1, T2, T3) { functionPointerToAdd(T1); };
Run Code Online (Sandbox Code Playgroud)
这条线就是问题所在.让我们分开吧:
auto myFunc = [&]
Run Code Online (Sandbox Code Playgroud)
这将创建一个未定义类型的局部变量,它接收一个lambda(很好)并启动一个lambda,它通过引用获取函数指针.指针将会消失,为了简单起见,最好使它成为[=](你将更多地复制一个完整的指针 - 没有大问题).
( returnType (*functionPointerToAdd)(T1) )
Run Code Online (Sandbox Code Playgroud)
这是lambda的参数.这意味着应该使用returnType(*)(T1)类型的函数指针调用lambda(!).这不是你想要的 - 你想用T1,T2,T3来调用它.
-> returnType (*)(T1, T2, T3)
Run Code Online (Sandbox Code Playgroud)
这定义了lambda的返回类型 - 只有那个.你现在要说它必须返回一个函数指针,返回一个函数返回一个returnType并将T1,T2和T3作为参数.然后是lambda类型
(returnType(*)(T1, T2, T3)) (*)(returnType(*)(T1))
Run Code Online (Sandbox Code Playgroud)
,或将函数指针作为参数并返回函数指针的函数.是的,它过于复杂且难以理解.
{ functionPointerToAdd(T1); };
Run Code Online (Sandbox Code Playgroud)
这最终是lambda的内容和错误的原因.您将类型T1作为参数传递给函数指针.
修复它的建议(因为语法非常复杂 - 我希望上面的文字可以帮助你改变我的原因:
auto myFunc = [=] ( T1 arg, T2, T3 ) -> returnType { return functionPointerToAdd(arg); }
Run Code Online (Sandbox Code Playgroud)
随意问为什么和如何.