|
The key here is that a parameter pack T... can be actually unpack into expressions, for example: template<class ...Args>
void g(Args... args) {
f(const_cast<const Args*>(&args)...);
// const_cast<const Args*>(&args) is the pattern, it expands two packs
// (Args and args) simultaneously
f(h(args...) + args...); // Nested pack expansion:
// inner pack expansion is "args...", it is expanded first
// outer pack expansion is h(E1, E2, E3) + args..., it is expanded
// second (as h(E1,E2,E3) + E1, h(E1,E2,E3) + E2, h(E1,E2,E3) + E3)
}
Taken from: http://en.cppreference.com/w/cpp/language/parameter_packSo for template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }
if you used this like overloaded<X, Y, Z> foo;
it would expand to struct overloaded : X, Y, Z {
using X::operator(), Y::operator(), Z::operator();
} foo;
EDIT: Removed stuff about the function since I was only guessing and Alexeiz answered it. The only thing I’ll add is that you can construct structs like this: struct Foo { int x; float y; };
Foo foo {1, 2.3};
overloaded is constructed from the three lambdas in the same way. I guess the deduction guide is needed because the compiler cannot deduce the template parameters from that initializer form, so the deduction guide tells it to use the types of the lambdas for the types of the template parameters.More information on deduction guides: http://en.cppreference.com/w/cpp/language/class_template_arg... (specifically, look for “Class template argument deduction of aggregates typically requires deduction guide” in the notes section for an example very like the overloaded one) |