c++boostboost-variant

Can boost variants safely be used with pointers to forward declared classes?


Can boost variant safely accept pointers to classes that are forward declared without any unintended implications such as using them with visitors?

class A;
class B;

typedef boost::variant<A*, B*> Variant;

class A {
public:
    A() {}
};

class B {
public:
    B() {}
};



Solution

  • I'd suggest using the builtin recursive element support for this exact purpose. It makes the (de)allocation(s) automatic and exception safe.

    Here's a complete demo where B actually recursively contains a vector<Variant> (which is 90% of the use-cases for forward-declared element types):

    Live On Coliru

    #include <boost/variant.hpp>
    #include <iostream>
    #include <iomanip>
    struct A;
    struct B;
    
    typedef boost::variant<A, B> Variant;
    
    struct A {
        int solution = 42;
    };
    
    struct B {
        std::string answer = "Thanks for all the fish!";
        std::vector<Variant> other { A{1}, A{2}, B{"Three", {}}, A{4} };
    };
    
    struct Visitor {
        std::string indent = " - ";
        void operator()(Variant const& v) const {
            boost::apply_visitor(Visitor{"  " + indent}, v);
        }
        void operator()(A const& a) const { std::cout << indent << a.solution << "\n"; };
        void operator()(B const& b) const {
            std::cout << indent << std::quoted(b.answer) << "\n";
            for (auto& v : b.other) {
                operator()(v);
            }
        };
    };
    
    int main()
    {
        Variant v;
        v = A{};
    
        boost::apply_visitor(Visitor{}, v);
    
        v = B{};
        boost::apply_visitor(Visitor{}, v);
    }
    

    Prints

     - 42
     - "Thanks for all the fish!"
       - 1
       - 2
       - "Three"
       - 4