3

I need to implement a safe array class that controls index when accessing underlying C array:

template <typename T, int N> class SafeArray
{
public:
    T &operator[](int index)
    {
        assert(0 <= index && index < N);
        return m_data[index];
    }
private:
    T m_data[N];
};

And instead of bool a[3];, now I write SafeArray<bool, 3> a;.

How do I support array initialization like bool b[3] = {false};? I mean what should I do to get b.m_data[] = {false, false, false} after SafeArray<bool, 3> b; has been constructed?

I guess I should add a constructor to SafeArray, but what would be a body of that constructor? Template parameter T can be anything, not necessarily bool. I am using pre-C++11.

8
  • std::initializer_list<T>.check out one of my questions Commented Jun 21, 2013 at 10:25
  • 1
    do you want to re-implement std::array<>? You could use just that, ot learn from reading the source Commented Jun 21, 2013 at 10:26
  • for pre-C++11, I felt that you could do something by preparing initialization template for each length. init template for length 2 will use init template for length 1 plus one more. mentioned somewhere, maybe in Alexandrescu's Modern C++ Design Commented Jun 21, 2013 at 10:29
  • @Nick and ForEveR oh sorry dint read that. Commented Jun 21, 2013 at 10:30
  • how can you safely do T m_data[N]; ? Commented Jun 21, 2013 at 10:30

3 Answers 3

2

I mean what should I to do to get b.m_data[] = {false, false, false} after SafeArray<bool, 3> b; has been constructed?

I am not sure I understand your question correctly, but if I do, then all you need to do is writing a default constructor that initializes your array:

SafeArray() : m_data()
{
}

The complete code:

template <typename T, int N> class SafeArray
{
public:
    SafeArray() : m_data()
    {
    }
    T &operator[](int index)
    {
        assert(0 <= index && index < N);
        return m_data[index];
    }
private:
    T m_data[N];
};

And a live example.

Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't SafeArray() : m_data() {} so the trick, without the call to std::fill?
@juanchopanza: D'oh! Yes, you're right. Going to edit, thank you
0

What about...?

SafeArray() {
    for (int i = 0; i < N; ++i) {
        m_data[i] = T();
    }
}

Comments

0

Since you are using C++03 (therefore you don't have std::array) I would rather recommend you boost::array which is, basically, a C++03 implementation of std::array. (Actually, std::array was inspired by boost::array).

Otherwise, make your class an aggregate, that is, (as per C++03 8.5.1/1)

An aggregate is an array or class (clause 9) with no user-declared constructor, no private protected non-static data member (clause 11), no base classes (clause 10), and no virtual functions.

Then your class will support aggregate initialization as you want.

Update: Reading the OP again (and Andy Prowl's answer), I'm not sure I understand the question. What I propose here is a way to initialize SafeArray at construction time, e.g.,

SafeArray<bool, 3> b = { false, false, false };

1 Comment

I thought about this too, but I think the OP wants to guarantee safe access, so they need to keep the array data member private - and that makes the class a non-aggregate

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.