I've seen code like the following popping up in C++17 codebases and have started using it myself:
template <class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts>
overloaded(Ts...)->overloaded<Ts...>;
int main()
{
std::variant<int, std::string> var = "foo";
std::visit(
overloaded{
[](int) {std::cout << "int\n"; },
[](std::string) {std::cout << "string\n"; }
},
var
);
}
and am trying to understand what overloaded
is actually doing. Without using variadic templates I believe the above expands to:
template <typename T, typename U>
struct overloaded : T, U {
using T::operator();
using U::operator();
};
template <typename T, typename U> // <-
overloaded(T, U)->overloaded<T, U>; // <- what is this?
I understand the definition of struct overloaded
: it is inheriting from what will be two lambdas which will have operator()
defined by virtue of being lambdas and saying to use those operator()
s as the function call operators of overloaded
. However, I don't even know what the other two lines are in terms of the semantics of C++: they seem to be making it so you can construct a struct overloaded
from arbitrary lambdas or something like that.