2

I tried to write a program with the following struct declaration:

struct N
{
    int value;
    N Left;
    N Right;
};

If that was possible, there would be an infinite number of structs in my program. I still want my Left and Right to have the exact same structure as N. Is there a way to do that?

2
  • 2
    You know that it's impossible, you even know why it's impossible, but you're still looking for a way to do it? Commented Aug 17, 2018 at 12:29
  • Recursion. "Pete and Repeat were on a boat. Pete fell off. Who was left?" How does the compiler know when to stop the recursive layout? Commented Aug 17, 2018 at 14:08

3 Answers 3

5

To build tree-like structures you may use pointers:

struct N {
    int value;
    N *left;
    N *right;
};

You may also use references:

struct N {
    int value;
    N &left;
    N &right;
};

but this way you'll need to carefully bind references in elements that don't have either of branches (or both.)

Or other indirecting types: unique_ptr, shared_ptr, reference_wrapper, etc.

Additionally, you can have a whole bunch of child referencnes:

struct N {
    int value;
    std::vector<std::reference_wrapper<N>> branches;
};
Sign up to request clarification or add additional context in comments.

9 Comments

No, you cannot use references. References must bind to a valid object at their initialization (Construction). Therefore it this will cause invalid references.
@GillBates they could, if they use a constructor. But it would probably not be very useful.
@GillBates N wat{42, wat, wat};? Or declare an external N null; and default left and right to it?
Yes, but can be rebound. Btw it's not hard to define a refernce wrapper that has null state.
|
2

I think im getting what your goal is. You want a struct that is aware of its neighbours. In that case use pointer instead.

struct N
{
    int value;
    N* Left;
    N* Right;
};

Comments

2

What is happening in your case is that the compiler is trying to generate your struct, but cannot because of infinite recursion: sizeof(N) = sizeof(int) + sizeof(N)

A way to solve this is to use pointers to N. Now : sizeof(N) = sizeof(int) + 2*sizeof(N*) is defined.

struct N { int value; N *left, *right; };

If you are using C++17, you can also use std::optional and std::reference_wrapper:

struct N { int value; std::optional<std::reference_wrapper<N>> left, right; };

Do Not Use References. References must bind during initialization and must bind to a valid object. Therefore, some of your references are bound to be invalid (since the tree is not infinite).

3 Comments

The optional example is incorrect, it would have infinite size too (optional is like the type with a validity flag tacked on)
@M.M You are right. I assumed it was implemented as a pointer :). How about std::optional<std::reference_wrapper<T>> thought?
Legal but I don't really see the advantage over N *. (It probably uses more storage, and is more cumbersome to access, for no clear benefit)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.