Search code examples
c++constructorcontainersstd

How to initialise custom vector type with a standard vector


I have created a sample container which internally stores in a std::vector. I want to be able to initialise the container with a std::vector. So I created constructors that take a std::initializer_list and also taking a begin and end.

But I can't seem to initialise like this:

const std::vector< uint8_t > vec1 { 1,2,3,4,5 };
UsingVectorExample ex{ vec1.begin(), vec1.end() };  // compilation errors on this line

What is the problem here? and how can I fix?

The code is here:

#include <vector>
#include <cstdint>

class UsingVectorExample
{
public:
    class iterator : public std::vector<uint8_t>::iterator
    {
    public:
        explicit iterator(typename std::vector<uint8_t>::iterator c)
            : std::vector<uint8_t>::iterator(c)
        {}
    };

    class const_iterator : public std::vector<uint8_t>::const_iterator
    {
    public:
        explicit const_iterator(typename std::vector<uint8_t>::const_iterator c)
            : std::vector<uint8_t>::const_iterator(c)
        {}
    };

    explicit UsingVectorExample(std::initializer_list<uint8_t> list)
        : m_vector(list.size())
    {
        m_vector.assign(list);
    }

    UsingVectorExample(iterator begin, iterator end)
        : m_vector(begin, end)
    {}

    UsingVectorExample(const_iterator begin, const_iterator end)
        : m_vector(begin, end)
    {}

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

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

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

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

    void push_back(const uint8_t& val)
    {
        m_vector.push_back(val);
    }

private:
    std::vector<uint8_t>  m_vector;
};


int main() {

    const std::vector< uint8_t > vec1 { 1,2,3,4,5 };
    UsingVectorExample ex{ vec1.begin(), vec1.end() };  // compilation errors on this line
}

Solution

  • The problem here is that your iterator constrcutors are explicit. That means vec1.begin() can't be converted to a UsingVectorExample::const_iterator without you doing it explicitly like

    UsingVectorExample ex{ UsingVectorExample::const_iterator{vec1.begin()}, 
                           UsingVectorExample::const_iterator{vec1.end()} }; 
                           
    

    To not have to do that, just remove the explicit. You can see that working in this live example