Reputation: 31
I know the title may be confusing. I created an "Array" data structure class which has a function called "Iterate". It accepts a function pointer (lambda) and iterates all the nodes with that function. Code:
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; });
This function works fine, but sometimes I need some arguments from outside to pass in. It can be done like this:
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);
And it works fine too, but I did not figure out how to do it with "...T". So the function can accept several arguments without having to overload the same function with x templates.
What I tried it:
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);
}
But it simply not works. It returns an error:
C++ no instance of overloaded function matches the argument list argument types are: (lambda []void (DataStructureType* data, Arg1 audio, Arg2 dt)->void, Arg1, Arg2)object type is: DataStructure<DataStructureType *>
Upvotes: 0
Views: 79
Reputation: 122350
Better not require a conversion to function pointer when not necessary. Only non capturing lambdas can convert to a function pointer. Once you fix that you can use a lambda expression that captures the additional parameter:
template <typename F>
void call_it(F f) {
for (int i=0;i<100;++i) f(i);
}
int main() {
auto f1 = [](int i,float x) {return i*x; };
float z = 0.2f;
call_it( [&](int i) { return f1(i,z); });
}
The problem with our approach is that you cannot have implicit conversions and template argument deduction at the same time. If you use an explicit cast it works:
template<class T,class ...U>
void iterate(void(*function)(T, U...), U... u) {
function(42, u...);
}
void foo(int,float) {}
int main() {
auto f1 = [](int i,float x) {};
iterate(static_cast<void(*)(int,float)>(f1),42.f);
}
Upvotes: 2