#include <iostream>
#include <utility>
#include <initializer_list>

template < typename T, std::size_t N > struct c_array
{
    static_assert( std::is_pod<T>::value, "must be a pod!" ) ;
    static_assert( N, "size must be a non-zero!" ) ;

    c_array() : a { T() } {}
    template < typename... U > c_array( U&&... args ) : a { args... } {} // ??

    c_array( std::initializer_list< std::pair<std::size_t,T> > il ) : c_array<T,N>()
    { for( const auto& p : il ) if(p.first<N) a[p.first] = p.second ; }

    T& operator[] ( std::size_t p ) { return a[p] ; }
    const T& operator[] ( std::size_t p ) const { return a[p] ; }

    T* begin() { return std::begin(a) ; }
    T* end() { return std::end(a) ; }
    const T* begin() const { return std::begin(a) ; }
    const T* end() const { return std::end(a) ; }

    T a[N] ;
};

int main()
{
    c_array<int,5> a ; // value initialized
    for( auto i : a ) std::cout << i << ' ' ; std::cout << '\n' ;

    c_array<long,6> b { 1, 2, 3, 4 };
    for( auto i : b ) std::cout << i << ' ' ; std::cout << '\n' ;

    // initialize by position, and value initialize unspecified positions
    c_array<short,8> c { { 1, 8 }, { 3, 9 }, { 5, 2 }, { 6, -1 } };
    for( auto s : c ) std::cout << s << ' ' ; std::cout << '\n' ;
}
