1

Looking at this example for std::visit from cppreference, I am having trouble understanding exactly how this compiles and works. In line 12 a function template ‘overloaded’ is defined, but no implementation for the function is supplied. This function is somehow (?) used by the std::visit in line 17 to deduce the type of the ‘struct overloaded’ based on the three lambdas.

How does this work?

And what really get’s me is that the template function ‘overloaded’ must have the same name as the ‘struct overloaded’ for it to compile. How is those related? My thinking was that the ‘template function overloaded’ was used to declare the type ‘struct overloaded’ for the compiler. But then I don’t understand why the curly braces must be used in line 17. Why not function parentheses?

Why this works eludes me.

#include <iomanip>
#include <iostream>
#include <string>
#include <variant>
#include <vector>

template<class T> struct always_false : std::false_type {};

using var_t = std::variant<int, long, double, std::string>;

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

int main() {
    std::vector<var_t> vec = {10, 15l, 1.5, "hello"};
    for (auto& v: vec) {
        std::visit(overloaded {                                       // Line 17
            [](auto arg) { std::cout << arg << ' '; },
            [](double arg) { std::cout << std::fixed << arg << ' '; },
            [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
        }, v);
    }
}   
Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
Generic Name
  • 1,083
  • 1
  • 12
  • 19

0 Answers0