Go through the constant from the structure to its pointer and reference elements

I have a pointer structure. I would like to do so if the struct instance is const, then the contents of its pointer cannot be changed.

struct Foo {};

struct Bar {
    Foo /*const goes here if `const Bar`*/ *foo;
};

void f(Bar& bar) {
    *bar.foo = Foo(); // OK
}

void g(const Bar& bar) {
    *bar.foo = Foo(); // OK - but should be error
}

Is there a way to pass a constant from a structure to its pointer and link elements?

+4
source share
3 answers

Encapsulation to the rescue!

Just select access through the interface:

struct Bar {
  Foo * getFoo() { return foo; }
  Foo const * getFoo() const { return foo; }
private:
  Foo *foo;
};

void f(Bar& bar) {
    *bar.getfoo() = Foo(); // OK
}

void g(const Bar& bar) {
    *bar.getfoo() = Foo(); // Error!
}
+6
source

You struggle with the tongue, do not do this. It’s like swimming upstream - you only tire yourself and are not like the result.

Your problem can be fixed using personal data and a member function to do the job:

struct Foo {};

struct Bar {
   void reset() {
      *foo = Foo();
   }
private:
    Foo  *foo;
};

void f(Bar& bar) {
    bar.reset();   // OK
}

void g(const Bar& bar) {
    bar.reset();   // fails, as reset is not declared const
}
+2
source

const propaging:

template<typename T>
struct const_ptr : std::unique_ptr<T> {
    using std::unique_ptr<T>::unique_ptr;

    const T& operator*() const {
        return std::unique_ptr<T>::operator*();
    }

    const T* operator->() const {
        return std::unique_ptr<T>::operator->();
    }

    T& operator*() {
        return std::unique_ptr<T>::operator*();
    }

    T* operator->() {
        return std::unique_ptr<T>::operator->();
    }
};

const const_ptr :

const_ptr<int> iptr = std::make_unique<int>(6);

*iptr = 7; // okay

const auto ciptr = std::move(iptr);

*ciptr = 2; // error

However, keep in mind that since we publicly distribute std::unique_ptr, its function is still available. You can use private inheritance and use all other functions except our custom one:

template<typename T>
struct const_ptr : private std::unique_ptr<T> {
    using std::unique_ptr<T>::unique_ptr;

    // Implement our operators like above

    using std::unique_ptr<T>::release;
    using std::unique_ptr<T>::reset;
    // .. all other public functions
};
+1
source

Source: https://habr.com/ru/post/1685343/


All Articles