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

泄露秘密 提交于 2019-12-04 22:30:37

To make multiple visitation cleaner. Let's say I had two std::variant<A,B>, one named left and one named right. With multiple visitation, I can write:

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

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

That's a pretty clean interface, and is something that's pretty commonly useful. It's also easy to implement efficiently - you just create a n-dimensional array of functions instead of a one dimensional array.

On the other hand, with only single visitation, you'd have to write:

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

That's miserable to write, miserable to read, and likely less efficient too.

einpoklum - reinstate Monica

Because we need to allow for visitation of combinations of classes within variants. That is, if we have

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

we can obviously use these kinds of visitors:

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

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

with Var1 and Var2 respectively. We can even use this next kind, with both Var1 and Var2 individually:

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

but what OP is missing is that we want to be able to visit one of the four pairs (A,C), (A,D), (B,C), (B,D) - when looking at a pair of Var1 and Var2 together. That's why the variadic argument to std::visit is all-but-necessary. An appropriate visitor would look like this:

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

and we would call std::visit(Visitor4{}, my_var1_instance, my_var2_instance);

I figured this out when reading Barry's answer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!