【发布时间】:2023-02-15 20:27:30
【问题描述】:
我知道标题可能令人困惑。 我创建了一个“Array”数据结构类,它有一个名为“Iterate”的函数。它接受一个函数指针 (lambda) 并使用该函数迭代所有节点。 代码:
void Iterate(void(*function)(T* value))
{
if (Empty()) return;
for (Node* iter = start; iter != nullptr; iter = iter->post)
function(iter->value);
}
// Function Call
DataStructure<int> test;
test.Iterate([](int i){ i = 0; });
这个函数工作正常,但有时我需要从外部传入一些参数。它可以像这样完成:
template<class U>
void Iterate(void(*function)(T* value, U a), U u)
{
if (Empty()) return;
for (Node* iter = start; iter != nullptr; iter = iter->post)
function(iter->value, u);
}
// Function call
DataStructure<int> test;
test.Iterate<float>([](int i, float e){ i = e; }, 10.f);
它也工作得很好,但我不知道如何用“...T”来做。因此该函数可以接受多个参数,而不必使用 x 模板重载同一个函数。
我尝试了什么:
template<class ...U>
void Iterate(void(*function)(T*, U...), U... u)
{
if (Empty()) return;
for (Node* iter = start; iter != nullptr; iter = iter->post)
function(iter->value, u);
}
但它根本行不通。它返回一个错误:
C++ 没有重载函数的实例匹配参数列表参数类型是:(lambda []void (DataStructureType* data, Arg1音频,Arg2dt)->void, Arg1, 精氨酸2)对象类型是:数据结构<数据结构类型*>
【问题讨论】:
-
"a function pointer (lambda)" 只有非捕获 lambda 可以转换为函数指针。如果你想要一个 lambda 作为参数,你不应该需要转换。
-
巧合的是,使用捕获是您问题的答案;)
-
请不要标记不相关的语言。 C语言标签在这里不适用。实际上,也不需要 C++11 和 C++14 标签。
-
另一方面,我建议您也为可调用对象使用模板,这样您就可以使用任何可调用对象,不仅是那些可以转换为指向非成员函数的指针。例如,您的代码目前无法处理带有捕获的 lambda-
-
至于你的问题,因为
u是一个参数包,你也需要...在某处。和我还建议你做一些研究完美转发和std::forward。