Search code examples
c++lambdamultiple-inheritancetemplate-argument-deductionc++17

C++17 Inheriting set of lambdas with template argument deduction guides


I was looking at the article on std::variant http://en.cppreference.com/w/cpp/utility/variant/visit

The example contains essentially the following lines (sligtly modified by me):

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

auto a = overloaded {
            [](auto arg) { std::cout << arg << ' '; },
            [](double arg) { std::cout << std::fixed << arg << ' '; },
            [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
           };

The code basically uses each lambda function in a list as a base class for the struct overloaded. The first line pulls lambda's operator() into the scope of the struct. The second line uses class template argument deduction guides (C++17).

question

I do not understand the line #3 with the use of { } braces after the overloaded.

What kind of C++ mechanism works here? Do we use the initialization list and convert it into a variadic template parameters or it is a kind of uniform/aggregate initialization? Is any actual constructor being called in this line?

Interestingly, the construction fails if I use ( ).


Solution

  • It's aggregate initialization, specifically of the direct public bases of the resulting type. Since C++17, the base subobjects don't have to be aggregates themselves, they are copy initialised from the elements of the initialiser list.