来自https://en.cppreference.com/w/cpp/utility/variant/visit:
visit?我不明白“访问者的选定调用”?示例代码
// Don't understand what this means, can explain? It's a templated func with trailing return type but no body?
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
// Why would the visitor function use && instead of &?
std::visit([](auto&& arg){std::cout << arg;}, v);
Run Code Online (Sandbox Code Playgroud)
了解访问者的最简单方法是将其与多态性进行比较。在多态类中,您有一个具有虚函数的基类和覆盖这些函数的派生类。您创建派生类的对象,并将它们存储为基类的对象(大多数情况下作为指针)。当您调用基类指针中的虚函数时,它们将从您最初创建的类型(即派生类类型)调用函数。
访问者完全相同,但类型安全。然而,访问者没有基本类型。您基本上将所有“派生”类型(即具有要调用的方法的类型)存储在变体对象中(它们并未真正存储,它们实际上是互斥的,这是变体的本质)。变体与其所持有的对象类型无关,就像基类与其所持有的派生类型无关一样。就像在基类指针中调用方法(上面提到的)一样,将导致在派生类中调用重写方法,这同样适用于变体。当您“访问”时,该类的正确变体将用于调用下面的函数。
这里有一个问题:当您将多个类型放入一个变体中,并访问其中的方法时,与多态类型结构不同,方法不必共享相同的返回类型。因此,如果一个类中的一个方法返回 int,而另一个类中的另一个同名方法返回 double,并且您访问包含两者的变体,则将返回正确的返回类型,具体取决于变体中实例化的类型。
文字太多了,我知道。希望有帮助。
从文档中返回std::visit访问者返回的内容。
访问者所选调用返回的值。
使用类似返回void的访问者[](auto&& arg){std::cout << arg;},std::visit将返回void
std::visit([](auto&& arg){std::cout << arg;}, v);
Run Code Online (Sandbox Code Playgroud)
使用类似返回var_t的访问者[](auto&& arg) -> var_t {return arg + arg;},std::visit将返回var_t
var_t w = std::visit([](auto&& arg) -> var_t {return arg + arg;}, v);
Run Code Online (Sandbox Code Playgroud)
这overloaded是创建访问者包装:
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
Run Code Online (Sandbox Code Playgroud)
然后您可以使用以下命令创建访客
auto visitor = overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
};
Run Code Online (Sandbox Code Playgroud)
接下来可以用以下方式调用:
std::visit(visitor, v);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,访问者返回void然后std::visit也返回void