tags:

views:

147

answers:

3
vector<int> l; 
for(int i=0;i<10;i++){ 
   l.push_back(i); 
} 

I want the vector to only be able to store numbers from a specified range (or set). How can that be done, in general?

In particular, I want to restrict the vector to beonly be able to store single digits.

So, if I do a l[9]++ (in this case l[9] is 9), it should give me an error or warn me. (because 10 is not a single digit number). Similarly, l[0]-- should warn me.

Is there a way to do this using C++ STL vector?

+2  A: 

Wrap it with another class:

class RestrictedVector{
private:
    std::vector<int> things;
public:
// Other things
    bool push_back(int data){
        if(data >= 0 && data < 10){
            things.push_back(data);
            return true;
        }
        return false 
    }
}
Brendan Long
This will not inhibit the use case that the question is about: incrementing a field already present. Even if it is a good step into providing that...
David Rodríguez - dribeas
+10  A: 

An alternative solution would be to create your own datatype that provides this restrictions. As i read your question I think the restrictions do not really belong to the container itself but to the datatype you want to store. An example (start of) such an implementation can be as follows, possibly such a datatype is already provided in an existing library.

class Digit
{
private:
    unsigned int d;
public:
    Digit() : d(0) {}
    Digit(unsigned int d)
    {
        if(d > 10) throw std::overflow_error();
        else this->d=d; 
    }
    Digit& operator++() { if(d<9) d++; return *this; }
    ...
};
KillianDS
+1, substitute `raise` by `throw std::overflow_error()`... but the approach is good
David Rodríguez - dribeas
Thanks for noticing, was mixing in some python there. I updated the code.
KillianDS
I'm positive someone like Sutter or Meyers wrote a nice `ranged_integer` class, but I cannot find it anywhere. In any case, a more generic version of this solution is of course possible. It would start with `template <typename T, T Min, T Max>` and you just plug in from there.
GMan
A: 

Convert the digit to a string and check against length > 1. Not the most elegant solution, but it will do what you want. You could also use divide by 10 - if i/10 >= 1, too big. if i<=0, warn too small.

Both moethods could be dropped into a container or done before the push.

Michael Dorgan
UncleBens
+1 UncleBens (converting to string to check numeric properties is tonailcurling)
peterchen