5

所以这个例子来自:http ://en.cppreference.com/w/cpp/utility/variant/visit声明了专门的类型:

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

在此处构造为 r 值:

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);

我试图弄清楚这是如何工作的。overloaded从这里继承的类型是什么?它看起来像一个 lambda 数组,但我不知道它会有一个operator(). 有人可以解释继承在这里是如何运作的吗?

4

1 回答 1

6

overloaded分别从每个 lambda 继承,每个 lambda 都有一个调用运算符。因此,您创建了一个结构,该结构在一个重载集中包含所有调用运算符。只要它们不模棱两可,就会自动选择正确的。

您可以想象要扩展为的可变参数模板

struct overloaded :
    // inherits from
    decltype([](auto arg) { std::cout << arg << ' '; }),
    decltype([](double arg) { std::cout << std::fixed << arg << ' '; }),
    decltype([](const std::string& arg) { std::cout << std::quoted(arg) << ' '; })

    // has three operator()s
    {
        using decltype([](auto arg) { std::cout << arg << ' '; })::operator();
        using decltype([](double arg) { std::cout << std::fixed << arg << ' '; })::operator();
        using decltype([](const std::string& arg) { std::cout << std::quoted(arg) << ' '; })::operator();
    };

除了在实际代码中它不起作用,因为具有相同主体的 lambdas 仍然具有不同的类型。

overloaded它为每个实例创建 1种具有多重继承的类型。

于 2017-06-07T13:54:59.180 回答