什么是类型此结构是继承?

时间:2017-06-07 13:51:09

标签: c++ operators variadic-templates specialization template-inheritance

所以来自this examplehttp://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从这里继承的类型是什么?它看起来像是一群lambdas,但我不知道它会如何产生operator()。有人可以解释继承在这里是如何工作的吗?

1 个答案:

答案 0 :(得分:6)

overloaded从每个lambda单独继承,每个lambda都有一个call运算符。因此,您创建一个在一个重载集中包含所有调用操作符的结构。只要它们不模糊,就会自动选择正确的。

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

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

除了真实的代码之外它不会起作用,因为具有相同主体的lambda仍然会有不同的类型。

它创建1 overloaded类型,每个实例化具有多个继承。