In addition to the other answers:
Be more direct towards the user
The template parameter n is not very explanatory, n pieces of what? In your case I can deduce it to be number of int that should back the array.
As a user I don't care how many ints are backing the array, in fact it's also a portability issue as an int can be anything from 16 bits and up. So to be sure I can get the number of bits I need, I need to figure out how big an int is on my platform.
All I really care about is:
Does it fit as many bits as I need?
For this reason you should make n be the minimum number of bits the array is guaranteed to hold. And figure out how many ints you need internally in the class.
Missing methods
#Missing methods
YouYou really should provide a size_t size() const method as well as a size_t capacity() const.
It would also be a good idea to provide overloaded BitProxy operator [](size_t i) where BitProxy is implicitly convertible to bool and has assignment operator that writes back into the array. This means that BitArray<n> ba; ba[3] = true; will set the fourth bit to true.
Off the top of my head (this probably doesn't compile but it shows the idea):
class BitProxy{
public:
BitProxy(BitArray& ba, size_t bit) : m_ba(ba), m_bit(bit) {}
operator bool(){ return m_ba.test(m_bit); }
BitProxy& operator = (bool v){
if(v) m_ba.set(v);
else m_ba.reset(v);
return *this;
}
private:
BitArray& m_ba;
size_t m_bit;
};
class BitArray{
public:
BitProxy operator [](size_t i){ return BitProxy(*this, i);}
};
Adoption to your templates and other missing operators such as bool operator == (bool v) and const correctness are left as an exercise for the reader.