views:

84

answers:

4

Given a class like this:

class Foo
{
   const int a;
};

Is it possible to put that class in a vector? When I try, my compiler tells me it can't use the default assignment operator. I try to write my own, but googling around tells me that it's impossible to write an assignment operator for a class with const data members. One post I found said that "if you made [the data member] const that means you don't want assignment to happen in the first place." This makes sense. I've written a class with const data members, and I never intended on using assignment on it, but apparently I need assignment to put it in a vector. Is there a way around this that still preserves const-correctness?

+2  A: 

Use a vector of pointers std::vector<Foo *>. If you want to avoid the hassle of cleaning up after yourself, use boost::ptr_vector.

Jesse Beder
Alright, thanks. I'll try this.
Max
+1  A: 
Owen S.
Making a variable static makes all instances of that class share it. If you actually need the constant to be unique to instances then this will definitely not work at all.
Noah Roberts
Hm, I might have misunderstood the use case. Is this a constant that needs to vary from instance to instance? I haven't yet run into the case where I've really needed one of those.
Owen S.
It is. In the program I'm writing, I have a Grid class, that has width and height variables. I never want the width and height to change once their initialized, so I make them constant, but I do want Grids of various sizes in a vector.
Max
+6  A: 

I've written a class with const data members, and I never intended on using assignment on it, but apparently I need assignment to put it in a vector. Is there a way around this that still preserves const-correctness?

You have to ask whether the following constraint still holds

a = b;
 /* a is now equivalent to b */

If this constraint is not true for a and b being of type Foo (you have to define the semantics of what "equivalent" means!), then you just cannot put Foo into a Standard container. For example, auto_ptr cannot be put into Standard containers because it violates that requirement.

If you can say about your type that it satisfies this constraint (for example if the const member does not in any way participate to the value of your object, but then consider making it a static data member anyway), then you can write your own assignment operator

class Foo
{
   const int a;
public:
   Foo &operator=(Foo const& f) {
     /* don't assign to "a" */
     return *this;
   }
};

But think twice!. To me, it looks like that your type does not satisfy the constraint!

Johannes Schaub - litb
So you're saying if I'm sure I'll never write `a = b` with my type, then it's okay to write an assignment operator that does nothing? Makes sense to me, but what makes you think my type does not satisfy that constraint?-EDIT- On second thought, I see what you're getting at better. I agree that my type does not satisfy the constraint.
Max
@Max: That's not what he's saying. He's saying do all the assignment like normal, but ignore the assignment of the `const` member. And the container is free to do `a = b`, it has nothing to do with what you'll do with it.
GMan
A: 

I'm considering making the data member non-const, but private and only accessible by a get function, like this:

class Foo
{
    private:
        int a;
    public:
        int getA() const {return a;}
};

Is this 'as good' as const? Does it have any disadvantages?

Max
We have no idea what you're doing with your data. but if it was originally `const` so clients of the class couldn't modify it, yes. This is known as encapsulation; make data private and expose it through methods.
GMan