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