user9614249
user9614249

Reputation:

How to construct a class with a constant reference cycle?

I am writing a toy program and I accidentally created a class that I don't know how to construct.

struct Parent;

struct Data {
  const Parent &parent;
  // ...
  Data(const Parent &parent) : parent(parent) {}
};

struct Parent {
  const std::vector<Data> datas;
  // ...
  Parent(std::vector<Data> &&data) : datas(std::move(data)) {}
};

Parent has a const list of Data. Each Data has a const reference to parent. One cannot exist without the other.

I can't use this constructor

Parent(std::vector<Data> &&data)

Because I can't construct Data without a reference to the already existing parent. But I cannot construct Parent without a vector of Data to initialize datas....

How can Parent be constructed so that each Data object contains a const reference back to the owning Parent object?

Upvotes: 1

Views: 61

Answers (2)

Brian61354270
Brian61354270

Reputation: 14434

You can use the fact that C++ allows self-referential declarations to create both the Parent and Data instances in the same statement:

Parent parent(std::vector{Data{parent}, Data{parent}});

Upvotes: 1

user9614249
user9614249

Reputation:

Based on Brian's answer, I was able to use a builder function that takes a const Parent & and builds an arbitrary vector of Data.

Then builder can be called from Parent's member initialization list with this.

struct Parent;
struct Data {
  const Parent &parent;
  // ...
  Data(const Parent &p) : parent(p) {}
};

std::vector<Data> builder(const Parent &p) {
    std::vector<Data> datas;
    datas.emplace_back(p);
    return datas;
}

struct Parent {


  const std::vector<Data> datas;

  Parent() : datas(builder(*this)) {}
};

See it on godbolt.

Upvotes: 0

Related Questions