寻求更好地理解标准::访问

Seek to understand std::visit better

本文关键字:标准 访问 更好      更新时间:2023-10-16

来自 https://en.cppreference.com/w/cpp/utility/variant/visit :

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

了解访客的最简单方法是将它们与多态性进行比较。在多态类中,您有一个基类(具有虚函数(和派生类(重写这些函数(。创建派生类的对象,并将它们存储为基类的对象(主要是指针(。在基类指针中调用虚函数时,它们将从您最初创建的类型(即派生类类型(调用函数。

访客完全相同,但类型安全。但是,访问者没有基本类型。你基本上将所有"派生"类型,即具有要调用的方法的类型,存储在一个变体对象中(它们并没有真正存储,它们实际上是互斥的,这是变体的性质(。变体与它所持有的对象类型无关,就像基类与它所持有的派生类型无关一样。就像在基类指针(如上所述(中调用方法一样,将导致在派生中调用重写方法,这同样适用于变体。当你"访问"时,类的正确变体将用于调用下面的函数。

这里有一个问题:当您将多个类型放在一个变体中,并访问其中的方法时,与多态类型结构不同,方法不必共享相同的返回类型。因此,如果类中的一个方法返回 int,而另一个类中具有相同名称的另一个方法返回双精度值,并且您访问包含两者的变体,具体取决于变体中实例化的方法,将返回正确的返回类型。

我知道文字太多了。希望有帮助。

从文档中,std::visit返回访问者返回的内容。

访问者的选定调用返回的值。

使用像[](auto&& arg){std::cout << arg;}一样返回void的访客,std::visit将返回void

std::visit([](auto&& arg){std::cout << arg;}, v);

使用返回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);

overloaded是创建访客包装

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

然后,您可以使用以下方法创建访问者

auto visitor = overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
};

接下来可以用:

std::visit(visitor, v);

在这种情况下,访客返回无效,然后std::visit也返回无效