1

Is it safe to modify a variant inside the visitor function?

struct visitor {
    visitor(std::variant<int, std::string> & var) : var(var){}

    void operator()(int i) {
        var = std::to_string(i);
    }

    void operator()(const std::string & s) {
        var = atoi(s.c_str());
    }
    std::variant<int, std::string> & var;
};

void convert(std::variant<int, std::string> & var) {
    std::visit(visitor{var}, var);
}

In the string reference function in the example above, I would assume that the string reference is valid until the assignment of the new value. But does the standard say anything about the validity of this use case?

jo-art
  • 215
  • 1
  • 9
  • 1
    Your visitor's operator() could also return a value so in convert() you write `var = std::visit(visitor, var);`. Doesn't answer your question but just a suggestion of a better design, in case you are not aware. – ypnos Apr 29 '20 at 10:14
  • @ypnos Thanks, Yes, i am aware of it, and it might be what I end up doing, but it would still be nice to know. – jo-art Apr 29 '20 at 10:31

1 Answers1

1

There is nothing special in your use case.

You create a functor which takes a reference to a variable. Fine. After that you call your functor with a reference to the content of that var. Why not? And after that, you modify it. Also fine.

You are not destroying anything which your references are pointing to and the order of all operations are well defined.

As this, the answer is: Yes, it is safe!

What you cannot do is use the reference of the content of the var after you modify the var itself. This will make your reference invalid. But you do not use it anymore, so the code is well-defined.

For example in your code:

void operator()(const std::string & s) {
    var = atoi(s.c_str());
    ## don't use "s" anymore, as s is invalidated by assigning a new value to var! ##
}
ypnos
  • 50,202
  • 14
  • 95
  • 141
Klaus
  • 24,205
  • 7
  • 58
  • 113