Home > other >  Is it safe to call std::visit on classes with virtual functions?
Is it safe to call std::visit on classes with virtual functions?

Time:01-13

I'd like to create a hierarchy of visitors to handle instances of std::variant. I'd like to override some of the methods in subclasses for more specialized behavior. My code looks like this:

#include <variant>
#include <cstdint>
#include <iostream>

struct Event1 {};
struct Event2 {};

using Event = std::variant<Event1, Event2>;

class Visitor {
public:
    virtual ~Visitor() = default;
    virtual void operator()(const Event1&) { std::cout << "Visitor: Event1\n"; }
    virtual void operator()(const Event2&) { std::cout << "Visitor: Event2\n"; }
};

class SubVisitor: public Visitor {
public:
    using Visitor::operator();
    virtual void operator()(const Event1&) { std::cout << "SubVisitor: Event1\n"; }
};

int main() {
    SubVisitor sv;  
    Event e;

    e = Event1{};
    std::visit(sv, e);  

    e = Event2{};
    std::visit(sv, e);
}

This compiles and seems to work fine:

$ g   test.cpp -o test
$ ./test 
SubVisitor: Event1
Visitor: Event2

Is such code well defined and carry no risk of an undefined behavior? All examples of std::variant I've seen use either simple classes with no inheritance or lambdas.

CodePudding user response:

Yes, such code is required to do what you expect. When you pass a Visitor & to std::visit, it won't copy (and thus slice) it.

All examples of std::variant I've seen use either simple classes with no inheritance or lambdas.

That's because examples tend to be as simple as possible.

  •  Tags:  
  • Related