在lambda中使用类模板参数时发生编译错误
Compilation error when using class template parameter in lambda
我正试图在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...
}
};
我试图做的是将函数指针包装在一个闭包中,该闭包的签名与类的完整模板类型匹配(有效地"丢弃"了设置为"Nil"的值(。我得到的错误是:
error C2275: 'T1' : illegal use of this type as an expression
我使用的是MSVC10,我尝试按照访问具有lambda的成员函数内部的类模板参数类型来对模板变量进行类型定义,但没有成功。我意识到这个特定的实现有几个问题,我稍后会遇到,但除此之外,我只是好奇为什么我不能在lambda语句中使用类的template参数。
我认为0x语法仍然有点混乱。
auto myFunc = [&] ( returnType (*functionPointerToAdd)(T1) ) -> returnType (*)(T1, T2, T3) { functionPointerToAdd(T1); };
这条线就是问题所在。让我们把它拆开:
auto myFunc = [&]
这将创建一个未定义类型的局部变量,该变量接收lambda(这很好(并启动lambda,该lambda通过引用获取函数指针。指针会消失,为了简单起见,最好将其设为[=](您将更多地复制完整的指针-没什么大不了的(。
( returnType (*functionPointerToAdd)(T1) )
这是lambda的参数。这意味着应该使用returnType(*((T1(类型的函数指针来调用lambda(!(。这不是你想要的——你希望它被称为T1,T2,T3。
-> returnType (*)(T1, T2, T3)
这定义了lambda的返回类型,并且仅定义了它。您现在说它必须返回一个函数指针,指向一个返回returnType并将T1、T2和T3作为参数的函数。lambda类型将是
(returnType(*)(T1, T2, T3)) (*)(returnType(*)(T1))
,或以函数指针作为参数并返回函数指针的函数。是的,它过于复杂和不可读。
{ functionPointerToAdd(T1); };
这最后是lambda的内容和错误的原因。您将类型T1作为参数传递给函数指针。
建议修复它(因为语法非常复杂-我希望上面的文本能帮助你了解我为什么更改了什么:
auto myFunc = [=] ( T1 arg, T2, T3 ) -> returnType { return functionPointerToAdd(arg); }
请随意询问为什么&怎样
我认为错误正是编译器所说的:您的调用functionPointerToAdd(T1)
没有意义。T1
是一种类型,而不是一个变量。lambda只接受函数指针作为参数,但没有实际的对象来调用函数!
另外,lambda应该返回什么?如果它的唯一目的是返回functionPointerToAdd(...)
,那么它的返回类型不应该只是returnType
吗?
也许是这样的(但我不完全理解你的要求(:
typedef returnType (*myFP)(T1);
auto myFunc = [] (myFP f, const T1 & t) -> returnType { return f(t); };
我还去掉了"通过引用捕获所有内容"([&]
(,因为您似乎没有使用任何非局部变量。
编辑:哦,等等,我明白了,你想把myFunc
添加到向量中。因此,您希望将给定的指针绑定到lambda,lambda的主体由调用函数组成。好的,让我们看看:
void operator+=(myFP f)
{
auto myFunc = [f] (T1 t, T2, T3) -> returnType { return f(t); };
the_vector.push_back(myFunc);
}
但我怀疑你是否能做到这一点,因为我相信,从环境中捕获的lambda不能转换为裸函数指针。我想,我们真的需要一个适合你的情况的函数对象。
- C++声明模板参数阴影模板参数错误
- 为什么 CRTP 模板C++给出无效参数错误?
- (C/C++)fscanf_s从txt文件以字符形式读取数组时缺少整数参数错误
- 参数错误可能与类型不匹配有关?
- printf 和 strftime 的参数错误无效
- 如何修复"ctypes"。参数错误:参数 2:<键入"异常.类型错误">:RaspberryPi 中的错误类型"错误
- 如何修复"没有重载函数需要 2 个参数"错误C++
- 术语不计算为函数采用 1 个参数错误?
- 从带有 getline() 的文件读入一行上有多个信息得到无效参数错误
- 为什么我不能像使用 std::string::size_type 那样使用 QList::size_type?(模板参数错误)
- cudaFreeHost() 无效参数错误
- 精神语法不会编译:函数模板参数错误?
- C 功能具有参考参数错误的迭代器错误.寻求解释
- 使用getDefaultCommConfig使用无效的参数错误
- C++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 处的类型/值不匹配
- 使用SWIG生成的Python库时,向量分配器参数错误
- 错误C2664:无法转换参数错误
- C 作为参数错误的功能
- 命令行参数错误
- 增强Python参数错误