c++classcircular-reference

C++ circular reference of classes members


I have the following code (simplified for brevity). I'm making an interpreter and executor of simple "programs", which basically consist of commands and loops.

class Command
{
    int code, arg; // whatever
};

class Loop;
class Statement;

class Scope
{
    std::vector<Statement> statements;
public:
    Statement& appendCmd(const Command& = {}); // works
    Statement& appendLoop(const Loop& = {}); // cannot convert from 'initializer list' to 'const Loop &'
    Statement& appendLoop(const Loop& = Loop()); // use of undefined type 'Loop'
};

class Loop
{
    Scope scope;
    int iters;
};

class Statement
{
    std::variant<std::monostate, Command, Loop> sttmnt;
};

The problem is, class Loop requires definition of class Scope for the member variable, while class Scope requires definition of class Loop to construct the default value of argument. How can I solve this? Also I'd rather not make any of them nested inside any other.

I already had this problem before, but it could be omitted by moving method definitions out of the header file. However default argument value must be in the header...

Edit: Updated the code which hopefully removes the UB of variant having undefined type.


Solution

  • I suppose one solution would be:

    #include <memory>
    #include <variant>
    #include <vector>
    
    class Scope;
    
    class Command
    {
        int code, arg; // whatever
    };
    
    class Loop
    {
        std::unique_ptr <Scope> scope;
        int iters;
    };
    
    using Statement = std::variant<std::monostate, Command, Loop>;
    
    class Scope
    {
        std::vector<Statement> statements;
    public:
        Statement& appendCmd(const Command& = {});
        Statement& appendLoop(const Loop& = {});
    };
    

    But @RetiredNinja's comment is highly relevant.