4

I am trying to create a sample array class which is initialiszed by a std::initializer_list. I would like to check if the size of the initializer list is not more than the size of the array during compile time. Since static assert can only evaluate constexpr, this code is not getting compiled.

#include<initializer_list>
#include<cstddef>

template <typename T , size_t _size>
class array
{

    private:
    T arr[_size];

    public:
    array()
    {
    }

    array(std::initializer_list<T> arrList)
    {
        static_assert(_size>arrList.size(),"too many initializers"); // error: non-constant condition for static assertion

    }

    ~array()
    {
    }

};

int main()
{
    array<int,4> arr = {1,2,3,4,5}; 


    return 0;
}

std::array already has this functionality, but i couldnt find its implementation in header file.

#include<array>

int main()
{
    std::array<int,5> arr= {1,2,3,4,5,6}; // error: too many initializers for ‘std::array<int, 5>’
    return 0;
    
}
1
  • 1
    For array it is not explicitly implemented. array uses aggregate initialization and there the compiler takes care, not the STL. Commented Mar 17, 2021 at 6:53

1 Answer 1

2

You can't do it with std::initializer_list, arrList.size() cannot be used in a constant expression, although its size() member function is declared as constexpr. Take a look at this question.

std::array uses aggregate initialization, it doesn't have a constructor that takes an std::initializer_list. This is how std::array is typically implemented:

template<typename T, std::size_t size>
struct array {
    T arr[size];
    /* member functions */
};

Alternatively (with slightly different syntax for calling a constructor), you can make a constructor that takes an array by reference:

template<typename T, std::size_t size>
class array {
public:
    template<std::size_t s>
    array(const T(& a)[s]) {
        static_assert(s <= size, "too many initializers");
    }
private:
    T arr[size];
};

Then

array<int, 4> arr({1, 2, 3, 4, 5}); // error: static_assert failed due to requirement
                                    // '5UL <= 4UL' "too many initializers"

will fail to compile thanks to static_assert. However, you'll need some tricks inside the array constructor to perform the actual initialization of arr data member (you can't do arr(a)).

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

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.