Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

struct with const member

I'm having some trouble with a template struct.

template<typename T>
struct A{
    const int v1;
    T* v2;
};

My purpose is to make v1 always not editable, while v2 should be editable if I use T and not editable if I use const T as type.

If I create constructor to initialize A, the struct becomes:

template<typename T>
struct A{
    const int v1;
    T* v2;
    A() : v1(-1) { v2=NULL; }
    A(int value) : v1(value) { v2=NULL; }
};

But then g++ says that I need a specific assignment operator:

error: non-static const member ‘const int A::v1’, can’t use default assignment operator

But my assignment operator should also allow editing of v1. The only thing I'd like to avoid is an edit from the outside, something like:

A a;
a.v1=10;

Is there any way to implement this (without creating getter/setter or using a pointer to a new A(int) with the desired value)?

What if I declare v1 as a const int * ? It could refer someway to some value, but it cannot edit it.

like image 201
Vektor88 Avatar asked Sep 20 '25 04:09

Vektor88


1 Answers

Here's a way to "expose" a public, read-only data member that is modifiable by the class's own member functions (including assignment):

template <typename T>
class Helper {
    friend class A;
    T *ptr;
    Helper &operator=(const Helper &rhs) = default; // in C++11
    Helper &operator=(const Helper &rhs) { ptr = rhs.ptr; } // in C++03
  public:
    Helper(T *ptr) : ptr(ptr) {}
    operator const int &() const { return *ptr; }
};

class A {
    int v1_;
  public:
    Helper<int> v1;
    A() : v1(&v1_) {} // although `A` should have a constructor that sets `v1_`
    A(const A &rhs) { v1_ = rhs.v1_; v1 = Helper<int>(&v1_); }
    A &operator=(const A &rhs) { v1_ = rhs.v1_; v1 = Helper<int>(&v1_); }
};

Now anyone outside the class A can use v1, but the only thing they can use it for is to get a const int& reference to v1_.

It is far easier just to give A a getter function that returns const int &, but if you really want the data member syntax then this provides it...

like image 196
Steve Jessop Avatar answered Sep 22 '25 17:09

Steve Jessop