I can not figure out why it does not allow me to directly initialize a vector using the following syntax:
stl::vector<int> v{1, 2, 3};
I have implemented from scratch both the vector and the initializer list classes.
The vector constructor (there is also a default constructor which just sets everything to 0):
vector(initializer_list<T> init) : m_capacity(init.size()), m_size(m_capacity), m_data(nullptr)
{
this->m_data = (T *)malloc(m_size * sizeof(T));
if (this->m_data == nullptr)
throw "malloc: Couldn't allocate memory!\n";
memcpy(m_data, init.begin(), m_size * sizeof(T));
}
This is my initializer_list class:
template <typename T> class initializer_list
{
public:
typedef const T* const_iterator;
typedef T* iterator;
private:
iterator m_begin;
size_t m_size;
constexpr initializer_list(const_iterator it, size_t size) noexcept : m_begin(it), m_size(size) { }
public:
constexpr initializer_list() noexcept : m_begin(nullptr), m_size(0) { }
constexpr const_iterator begin() const { return m_begin; }
constexpr const_iterator begin(initializer_list<T> init) noexcept { return init.begin(); }
constexpr const_iterator end() const { return m_begin + m_size; }
constexpr const_iterator end(initializer_list<T> init) noexcept { return init.end(); }
constexpr size_t size() const { return m_size; }
};
I created a separate constructor in the vector class which takes a initializer list as parameter. However I get the following error:
no instance of constructor "stl::vector<T>::vector [with T=int]" matches the argument list
std::initializer_list
is a magic type that can't be implemented by user code.
The special behavior of overload resolution and braced initializer lists work only specifically for that magic std::initializer_list
type.
You can't define your own initializer_list
and hope for it to work like std::initializer_list
.
You also can't make the stl::vector<int> v{1, 2, 3};
syntax work without using std::intializer_list
. There is no way around using it. The syntax can't be achieved in any other way.
The standard library has a lot of these magic types and functions btw. Some of them are simply unimplementable by user code and need to rely on compiler builtins instead. But some, such as std::initializer_list
, also have special meaning to the compiler itself and couldn't even be replicated using the compiler's builtins.