I'm trying to assign a lambda to my std::function that contains 1 call to Test for each type specified in the parameter pack, does anyone know how to do this?
template<typename T>
void Test() {
}
template<typename ... Ts>
void Expand() {
std::function<void(void)> func = [Ts] {
for (const auto& p : { Ts... })
Test<Ts...>();
};
}
int main(int argc, char** argv) {
Expand<int, char>();
}
I am trying to have this expand to...
Test<int>();
Test<char>();
template<typename ... Ts>
Ts
here represents types. Template parameters are types.
[Ts] {
// ...
}
A lambda's capture captures values, and discrete objects rather than types. There's no such thing as a capture of types.
for (const auto& p : { Ts... })
Range iteration iterates over values in some container. A braced initialization list is a list values too, not types.
The major confusion here is the confusion between types and values, in C++.
If the intent is to generate "call to Test for each type specified in the parameter pack", then the simplest solution is to use C++17's fold expression:
template<typename ... Ts>
void Expand() {
std::function<void(void)> func = [] {
( Test<Ts>(), ...);
};
}
You tagged your question as C++11, but in the year 2022 it is highly likely that your compiler support C++17 as well.
In the unlikely event that you're limited to C++11, a helper throwaway void function can be used as a crutch:
template<typename ...Args>
void ignore_me(Args && ...args)
{
}
template<typename ... Ts>
void Expand() {
std::function<void(void)> func = [] {
ignore_me( (Test<Ts>, 0)...);
};
}