2

I am trying to initialize_list for a class template. I am fairly a newbie and have had some trouble with this. Error on main()

#include <iostream>
#include <initializer_list>
#include <stdexcept>

template <class T>
class Storage
{
private:
    int nrOfEl{ 0 };
    T *m_array{};
public:
//...
    Storage(std::initializer_list<T>& list)
        : Storage( static_cast<int>(list.size()) )
    {
        int count{ 0 };
        for (auto& element : list)
        {
            m_array[count] = element;
            ++count;
        }
    }

    ~Storage()
    {
        std::cout << "\nCalling ~Storage()\n";
        delete[] m_array;
    }

    T& operator[](const int &index)
    {
        if (index >= nrOfEl || index < 0)
            throw std::out_of_range("OUT OF BOUNDS");
        return *m_array[index];
    }

    Storage& operator=(std::initializer_list<T>& list)
    {
        int length{ static_cast<int>(list.size()) };
        if (length != nrOfEl)
        {
            delete[] m_array;
            nrOfEl = length;
            m_array = new int[length];
        }

        int count = 0;
        for (int element : list)
        {
            m_array[count] = element;
            ++count;
        }

        return *this;
    }
//...
};

int main()
{
    Storage<int> ints { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
        //error here
    return 0;
}

error C2440: 'initializing': cannot convert from 'initializer list' to 'Storage'

note: No constructor could take the source type, or constructor overload resolution was ambiguous

0

3 Answers 3

2

A note in addition to other answers: there is no reason to pass std::initializer_list by const&, it is just a pair of pointers (or a pointer and a size). You can pass it by value, just as it is done in the Standard library.

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

1 Comment

Best answer. If only I could up-vote multiple times!
1

In main(), your initializer list is constructed as an r-value, so pass-by-reference will fail. Passing by const-reference, however, will work. You should allow the constructor to accept const-reference lists:

Storage(const std::initializer_list<T>& list)
//      ^^^^^
    : Storage( static_cast<int>(list.size()) )
{
    int count{ 0 }; 
    for (const auto& element : list)    // const here too
    {
        m_array[count] = element;
        ++count;
    }
}

You should also change the parameter likewise with operator=.

1 Comment

C++ const correctness: yes, it's that important!
1

You have two issues:

  1. You are passing the initiliazer list by non-const reference into the Storage() constructor.
  2. You have not defined a Storage(int) constructor.

This should fix both:

Storage(std::initializer_list<T> const& list)
    : nrOfEl( static_cast<int>(list.size()) )
{ ... }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.