3

I wrote a custom array container, as most C++ libraries including std::array and std::iterator are not available for the target (embedded). The template class is mostly working as intended.
However I did not manage to set up a constructor, which can initialize the whole array without creating copies. I tried several constructors including passing by reference. The one shown will create a copy and has issues if the size of the passed array does not match the one of my class.

Language features up to C++11 are supported in the environment, but no std libraries are available. Therefore the answers to similar questions could not be used.

The sourcecode of the template class:

template<typename T, typename sizetype, sizetype SIZE>
class mArray
{
private:
    T _elements[SIZE]; ///< Array of SIZE elements of Type T
    static_assert( SIZE > 0, "Size must be > 0"); // Discourage empty array
public:
    mArray(){};
    mArray(T initArr[SIZE])
    {
        sizetype index = 0;
        for (auto element : _elements)
        {
            _elements[index] = initArr[index]; //
            ++index;
        }
    }
    T* begin()
    {
        return &_elements[0]; // Pointer to first _element
    }
    T* end()
    {
        return &_elements[SIZE]; // Pointer behind last _elements
    }
    T front()
    {
        return _elements[0]; // Return first element of _elements
    }
    T back()
    {
        return _elements[SIZE-1]; // Return last element of _elements
    }
    T at(sizetype pos)
    {
        static_assert( pos > SIZE, "pos must be < SIZE");
        return _elements[pos];
    }
    T operator[](sizetype pos)
    {
        return _elements[pos];
    }
    T* data()
    {
        return *_elements;
    }
    sizetype size()
    {
        return SIZE;
    }
};

How can I improve the constructor to avoid creating copies?

Community
  • 1
  • 1
Grebu
  • 205
  • 3
  • 7
  • 1
    You have a weird definition of "working as intended". Half of those member functions are broken. – T.C. Dec 28 '15 at 23:12
  • @T.C. So far I did not use all member functions, thus possibly avoiding existing errors. Due to lack of experience I do not see the faults. Should I open an additional question to find out about the major flaws? Or is there an example I could compare too, to find them by myself? Actually I found one now so I corrected the back() function. – Grebu Dec 28 '15 at 23:21
  • 1
    if you want to get errors from everything you can explicitly instantiate the template by writing `template class mArray;` or some such thing at the global level. – Ryan Haining Dec 28 '15 at 23:37

1 Answers1

1

The way this is done involves aggregate initialization. If you are trying to take an array and copy from it, that will of course require copies. However, if you are being passed an initializer list then you just need to make elements public and go with the std::array syntax:

template<typename T, typename sizetype, sizetype SIZE>
class mArray {
 public:
  T elements_[SIZE];
  static_assert( SIZE > 0, "Size must be > 0");
  T operator[](sizetype pos) { // you sure about this?
    return elements_[pos];
  }

  // other member functions
};

int main() {
  mArray<int, std::size_t, 10> arr{{1, 3, 5, 7}};
}
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174