2

A really quick question about some code that does not compile. I wrote a wrapper around std::vector:

template <class T>
class CLArray
{
public:
    /// Constructor, destructor.
    CLArray( const size_t size );
    CLArray( const size_t size, const T value );
    ~CLArray();

    /// Copy constructor and copy assignment operator.
    CLArray( const CLArray& rhs );
    CLArray& operator=( const CLArray& rhs );

    /// Move constructor and move assignment operator.
    CLArray( CLArray&& rhs );
    CLArray& operator=( CLArray&& rhs );

    void swap( CLArray& other )
    {
        std::swap( data_, other.data_ );
    }

    typedef typename std::vector<T>::iterator iterator;
    typedef typename std::vector<T>::const_iterator const_iterator;

    iterator begin()
    {
        return data_.begin();
    }

    const_iterator begin() const
    {
        return data_.begin();
    }

    iterator end()
    {
        return data_.end();
    }

    const_iterator end() const
    {
        return data_.end();
    }

    T& operator[]( const size_t index ) throw(CLException);
    T  operator[]( const size_t index ) const throw(CLException);

    T At( const size_t index ) const throw(CLException);
    void SetAt( const size_t index, const T& value ) throw(CLException);

    void Insert( ubyte* data, const size_t size );

    size_t GetSize() const;

    const CLArray<T>& GetData() const;

    void Clear();

private:
    std::vector<T> data_;
};

and I want to create a class for managing a 2 dimensional CLArray:

template <class T>
class SomeMap
{
public:
    SomeMap( const size_t width, const size_t heigth, const T defaultVal = 0 )
        : map_( width, CLArray<T>(heigth, defaultVal) )
    {
        // Allocate enough memory for all objects
    }

    ~SomeMap() {}

private:
    CLArray<CLArray<T>> map_;
    //std::vector<std::vector<T>> map_;
};

And I get an error: no matching function for call to ‘CLArray<Cell*>::CLArray() when declaring an object SomeMap<Cell*> map( 748, 480, nullptr ); and I do not really understand why... `

Athanase
  • 933
  • 9
  • 25

2 Answers2

1

You class CLArray<> lacks a default constructor. This is required for the type argument to std::vector<type> and used in its default constructor. In your case type=CLArray<Cell*>.

Btw, never a good idea to wrap a working code without adding any functionality.

Walter
  • 44,150
  • 20
  • 113
  • 196
  • Hi, thanks for the answer. I needed a wrapper because I want to limit the usage of vector (forbid the usage of push_back for example) but I want to use something that works (std::vector is quite robust :)). – Athanase Sep 16 '13 at 13:41
  • It works, thanks for the usefull answer, that was a dummy question ! – Athanase Sep 16 '13 at 13:48
1

CLArray has no default constructors, several methods of vector require T to be default constructible

When you instantiate this:

SomeMap<Cell*> map( 748, 480, nullptr );

SomeMap has a private member:

CLArray<CLArray<T>> map_;

CLArray stores vector<T> in the case of your private member, T is CLArray. This make's SomeMap's member evaluate to vector<CLArray<Case*>> and vector requires the contained object be default constructable. CLArray has no default constructors. Therefore you get a compiler error probably deep in vector`s code where it tries to instantiate a T.

You might expect that CLArray should have a default constructor. However, when you specify any constructor, you lose the default constructor that C++ gives you by default. (see here).

Community
  • 1
  • 1
Doug T.
  • 64,223
  • 27
  • 138
  • 202
  • 1
    Does std::vector really require its template parameter to be default constructible? It really depends on what member functions/constructors you call. – mfontanini Sep 16 '13 at 13:44
  • It works, thanks for the usefull answer, that was a dummy question ! – Athanase Sep 16 '13 at 13:49
  • @mfontanini you're right. You can avoid having a default constructor, but it makes using some of the methods of vector rather awkward to use because you have to pass in an instance – Doug T. Sep 16 '13 at 13:51