0

I define a class like this

#include<array>
template<class T,size_t D> 
class vec{
    private:
        std::array<T,D> arr;
    public:
        vec(std::initializer_list<T> l) : arr(l){ }
};

Then I construct the object of this class like this.

vec<int,3> v = {1,2,3};

Then I get an error

main.cpp:5:26: error: cannot bind non-const lvalue reference of type ‘std::initializer_list<int>&’ to an rvalue of type ‘std::initializer_list<int>’
     vec<int,3> v = {1,2,3};
                          ^
In file included from main.cpp:1:
vec.hpp:12:9: note:   initializing argument 1 of ‘vec<T, D>::vec(std::initializer_list<_Tp>&) [with T = int; long unsigned int D = 3]’
         vec(std::initializer_list<T>& l) : arr(l){ }

I wonder how can I make the aggregated initialization in my constructor valid.

0

2 Answers 2

2

A std::array is not constructable from a std::initializer_list. You have two options to fix this if you want to keep the std::array member. You can make vec and aggregate by making arr public and removing the constructor like

#include<array>
template<class T,size_t D> 
class vec{
    public:
        std::array<T,D> arr;
};

int main()
{
    vec<int,3> v = {1,2,3};
}

or you keep it as you have it but instead you iterate over arr and assign it values from the initializer list. That would look like

#include<array>
template<class T,size_t D> 
class vec{
    private:
        std::array<T,D> arr;
    public:
        vec(std::initializer_list<T> l)
        {
            std::copy_n(l.begin(), std::min(l.size(), arr.size()), arr.begin());
        }
};

int main()
{
    vec<int,3> v = {1,2,3};
}

This method does require the array members to be default constructable. If you can't/don't want to guarantee that then you need option one or switch to using a different type for arr like std::vector.

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

3 Comments

Thank you very much. It really helps. Do you mind explaining more to me about the default constructor? I wonder if I have two std:: array members arr1 and arr2 in class vec, will v={1,2,3} also work? Thank you.
@Richard In my second example since we are in the body of the constructor that means that arr was already default constructed. In order for that to happen that means T needs to be a type that has a default constructor. If T is a type that doesn't have a default constructor then you'll get an error because that means it can't default construct arr. You can you either method for two arrays. You would just need to use two lists like vec v = {{1,2,3},{3,4,5}}
Yeah, I understand.Thank you very much for your help.
0

std::array does not have any constructors. It has only aggregate initializer. If you replace std::array by std::vector it should works because vector has initializer list constructor.

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.