Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ type to hold members that can't be initialized in the constructor

Tags:

c++

I have some members that can't be initialized at construction time of the container class because the information to construct them is not available. At the moment I'm using std::unique_ptr to construct them later when the information becomes available.

The dynamic allocation/indirection is an unnecessary overhead as I know they will be constructed eventually. I could use std::optional, but I feel the semantics of std::optional will make the ones reading the code think the members are somehow optional and they might be missing which is not the case.

Is there any std library type that can hold a type for later construction with better semantics than std::optional?

EDIT: example code

struct Inner
{
    Inner(int someValue)
        : internalValue(someValue)
    {}

    int internalValue;
};

struct Outer
{
    Outer(){/*...*/}

    void createInner(int someValue)
    {
        assert(inner == nullptr);
        inner = std::make_unique<Inner>(someValue);
    }

    // I would like to avoid the dynamic memory allocation here
    std::unique_ptr<Inner> inner;
};
like image 339
Mircea Ispas Avatar asked Jan 24 '23 04:01

Mircea Ispas


1 Answers

std:::optional is what you are looking for, eg:

#include <optional>

struct Inner
{
    Inner(int someValue)
        : internalValue(someValue)
    {}

    int internalValue;
};

struct Outer
{
    Outer(){/*...*/}

    void createInner(int someValue)
    {
        inner = Inner(someValue);
    }

    std::optional<Inner> inner;
};

If you don't like how optional looks in your code, you can simply define an alias to give it a more suitable name for your situation, eg:

#include <optional>

struct Inner
{
    Inner(int someValue)
        : internalValue(someValue)
    {}

    int internalValue;
};

template<typename T>
using delayed_create = std::optional<T>;

struct Outer
{
    Outer(){/*...*/}

    void createInner(int someValue)
    {
        inner = Inner(someValue);
    }

    delayed_create<Inner> inner;
};
like image 76
Remy Lebeau Avatar answered Jan 30 '23 08:01

Remy Lebeau