繁体   English   中英

为什么std :: visit采用可变数量的变体?

[英]Why does std::visit take a variable number of variants?

为了更加熟悉C ++ 17,我刚刚注意到std::visit

template <class Visitor, class... Variants>
constexpr /*something*/ visit(Visitor&& vis, Variants&&... vars);

为什么std::visit不采用单个变体,而是任意数量的变体? 我的意思是,您始终可以使用一些标准库函数,并让其以相同的角色使用多个参数,并对所有参数进行处理(例如,容器中多个元素的std::find() ); 否则您可能会吸引多个访客,并在同一个变体上使用他们。

那么,为什么要进行这种特定的“变异化”?

为了使多次访问更清洁。 假设我有两个std::variant<A,B> ,一个命名为left ,另一个命名为right 经过多次访问,我可以写:

struct Visitor {
    void operator()(A, A);
    void operator()(A, B);
    void operator()(B, A);
    void operator()(B, B);
};

std::visit(Visitor{}, left, right);

这是一个非常干净的界面,并且通常非常有用。 有效实施也很容易-您只需创建n维函数数组即可,而不是一维数组。

另一方面,只需单次访问,​​您就必须编写:

std::visit([&](auto l_elem){
    std::visit([&](auto r_elem){
        Visitor{}(l_elem, r_elem);
    }, right)
}, left);

这样写起来很痛苦,阅读起来很痛苦,而且效率可能也较低。

因为我们需要允许访问变体内的类组合 也就是说,如果我们有

using Var1 = std::variant<A,B>;
using Var2 = std::variant<C,D>;

我们显然可以使用以下类型的访问者:

struct Visitor1 {
    void operator()(A);
    void operator()(B);
};

struct Visitor2 {
    void operator()(C);
    void operator()(D);
};

分别使用Var1Var2 我们甚至可以单独使用Var1Var2使用以下类型:

struct Visitor3 {
    void operator()(A);
    void operator()(B);
    void operator()(C);
    void operator()(D);
};

但什么OP缺少的是,我们希望能够访问四对一(A,C) (A,D) (B,C) (B,D) -在看一对时Var1Var2 在一起 这就是为什么std::visit的可变参数完全必要的原因。 合适的访问者如下所示:

struct Visitor4 {
    void operator()(A,C);
    void operator()(A,D);
    void operator()(B,C);
    void operator()(B,D);
};

我们将调用std::visit(Visitor4{}, my_var1_instance, my_var2_instance);

在阅读巴里的答案时,我发现了这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM