Is it possible to initialize a data member as const based on a bool passed in as argument in the constructor?

Viewed 104

I have a class that takes in a boolean called fixed as an argument. I want it to initialize the data member position as const if fixed is true. Is this possible at all?

class PhysicsVertex 
{
public:
    PhysicsVertex(olc::vf2d position, const bool fixed = false) :
          position(position), fixed(fixed)
    {
    }
    olc::vf2d position; //make this const if fixed is true.
    const bool fixed = false;
};

int main()
{
    PhysicsVertex v1{ {0, 0}, true }; //initialize v1.position as const
    PhysicsVertex v1{ {0, 0} }; //initialize v1.position as non-const
}
2 Answers

If your information about fixed parameter is needed at compile time then you can use templates

#include <type_traits>

struct vf2d
{
};
template <bool fixed>
class PhysicsVertex
{
public:
    PhysicsVertex() :
        position()
    {
    }
    typename std::conditional<fixed, const vf2d, vf2d>::type position;
};

void foo()
{
    auto vertex = PhysicsVertex<true>();
    //  vertex.position = vf2d(); - compile time error, you cannot change const member
    auto vertex2 = PhysicsVertex<false>();
    vertex2.position = vf2d(); // It works fine, you can change non const member
}

const class members are problematic, because they inhibit a whole bunch of compiler generated methods. For example PhysicsVertex cannot be copied. Often the better alternative is to not make it const but instead provide no means to modify it from outside the class:

class foo {
    int x = 42; 
public:
    int get() { return x; }
};

The member is not modifyable.

Now to your quesiton. You cannot make it const or non-const based on a runtime value (at least not easily), but following the suggestion above you can conditionally allow to modify it or not:

 class foo {
     int x = 42;
     bool modifyable = false;
 public: 
     foo(bool modifyable) : modifyable(modifyable) {}
     void set(int y) {
          if (!modifyable) throw "cannot modify";
          x = y;
     }
  };

You should reconsider whether you can already decide to make it const or non-const at compile time, because then you need not rely on runtime checks and excpetions but can use the approach described in this answer.

Related