1

When I was reading this paper, I saw lambdas being overloaded in the Recursive Lambdas section. I was confused as I've never saw that before and I thought it might be a new keyword in C++ that I didn't hear about before.

Turns out, it is not a keyword, but a helper function/class that just wasn't defined in the paper. I finally found some information on it on cppreference.com std::visit page.

In the example provided, I understood everything that was happening except for one thing:

// helper type for the visitor #4
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
...
int main() {
...
        // 4. another type-matching visitor: a class with 3 overloaded operator()'s
        std::visit(overloaded {
            [](auto arg) { std::cout << arg << ' '; },
            [](double arg) { std::cout << std::fixed << arg << ' '; },
            [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
        }, v);
}

As I understand it, using braces (overloaded{...}) would indicate that the constructor is being called, but there isn't one, and even if it had called the overloaded function, it has no body.

So, my question is: What's happening here? I found some reference that it is using user-defined deduction guides, but I'm still not clear.

EDIT

The crux of this, is my misinterpretation of:

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

This is not a free template function declaration, but a (tl;dr) user-defined deduction guides, which states what the default template class parameters should be for the constructor.

This is only barely tangentially related to What are Aggregates and PODs and how/why are they special?, which is what this question was marked as a duplicate of, and is only briefly mentioned in an answer entitled What will change for C++20.

Community
  • 1
  • 1
Adrian
  • 10,246
  • 4
  • 44
  • 110
  • Since you are familiar with cppreference.com, search it for the following keywords: "aggregate initialization" and "uniform initialization syntax". This is a clever combination of using deduction guides together with aggregate initialization. – Sam Varshavchik Apr 28 '19 at 18:43
  • Try reading [this article](https://dev.to/tmr232/that-overloaded-trick-overloading-lambdas-in-c17); it may help. – ravnsgaard Apr 28 '19 at 18:44
  • @SamVarshavchik: The correct term is "list initialization". – Nicol Bolas Apr 28 '19 at 18:47
  • Thanks @ravnsgaard, I already read that, and it's not helped. – Adrian Apr 28 '19 at 18:55
  • @NicolBolas, I don't think that this question that you posted is a duplication of this one. I understand what an aggregate is, as well as what *"list initialization"* is. However, this syntax is strange. I guess that aggregate initialization can be happening on the base types, in the order that they appear, and that the `overloaded` helper function seems to be generating the type, but the helper function has no body, and I would have expected the call to the helper function to be `overloaded(...)` or even `overloaded({...})` neither of which work. This is what my question is about. – Adrian Apr 28 '19 at 19:17
  • 1
    @Adrian `overloaded` is not a helper function, it's a struct. The second line is the deduction guide the type is deduced from the types of the parameters passed to the constructor. – super Apr 28 '19 at 19:28
  • @super, ah, of course. Now I understand! I had the answer. I just didn't go far enough in my research. Thanks. – Adrian Apr 28 '19 at 19:40

0 Answers0