Can I initialize an array using the std::initializer_list instead of brace-enclosed initializer?

后端 未结 3 917
轻奢々
轻奢々 2020-12-16 17:24

Can I initialize an array using the std::initializer_list object instead of brace-enclosed initializer?

As known, we can do this: http://en.cppreference

3条回答
  •  半阙折子戏
    2020-12-16 18:01

    Other answered correctly said this is not possible upfront. But with little helpers, you can get pretty close

    template
    std::array make_array_impl(
        std::initializer_list t,
        std::index_sequence) 
    {
        return std::array{ *(t.begin() + Ns) ... };
    }
    
    template
    std::array make_array(std::initializer_list t) {
        if(N > t.size())
           throw std::out_of_range("that's crazy!");
        return make_array_impl(t, std::make_index_sequence());
    }
    

    If you are open to more work arounds, you can put this into a class to catch statically-known length violations for the cases where you pass a braced init list. But be warned that most people who read this code will head-desk

    template
    struct ArrayInitializer {
        template struct id { using type = U; };
        std::array t;
    
        template>
        ArrayInitializer(typename id::type z) 
            :ArrayInitializer(z, std::make_index_sequence())
        { 
            if(N > z.size())
                throw std::out_of_range("that's crazy!");
        }
    
        template
        ArrayInitializer(U &&... u)
           :t{ std::forward(u)... }
        { }
    
    private:
        template
        ArrayInitializer(std::initializer_list& t,
                         std::index_sequence)
           :t{ *(t.begin() + Ns) ... }
        { }
    };
    
    template
    std::array f(ArrayInitializer ai) {
        return std::move(ai.t);
    }
    
    int main() {
       f({1, 2, 3, 4, 5});  // OK 
       f({1, 2, 3, 4, 5, 6});  // "too many initializers for array"
    
       std::initializer_list il{1, 2, 3, 4, 5};
       f(il); // ok
    }
    

    Note that both the non-static case at the top of the answer and the "head-desk" case do only check whether you provide too few initializing elements, and errors out then, for the initializer_list case. If you provide too many for the initializer_list case, the trailing elements are just ignored.

提交回复
热议问题