Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a template sized array?

I want to initialize a template sized array of objects with no default constructors, as shown in following code :

#include <array>

template<std::size_t N>
class Foo
{
    public:
        class Bar
        {
                Foo<N> & _super;

            public:
                Bar(Foo<N> *super) :
                    _super(*super)
                {
                }
        };

        std::array<Bar, N>  _array;

        Foo(void) :
            _array{{}} // We need {this, ...} N times
        {
        }
};


int main(void)
{
    Foo<3>  foo;
    (void)foo;
    return 0;
}

Is it a way to say : "I want an array of N objects, all initialized with this same parameter" ? I think there is a way with the template meta programming, but I cannot figure how to do it.

like image 232
Boiethios Avatar asked Apr 25 '16 13:04

Boiethios


2 Answers

Everything is possible with the little help from make_index_sequence:

   Foo() : Foo(std::make_index_sequence<N>()) {} 
   template <size_t... I> Foo(std::index_sequence<I...> ) : _array{((void)I, this)...} {}

Notice the comma operator (,) in the _array constructor - courtesy of @Quentin (as opposed to function call).

like image 50
SergeyA Avatar answered Oct 23 '22 07:10

SergeyA


You could just keep adding one this at a time until you have N of them, at which point you just initialize _array:

    Foo()
    : Foo(this)
    { }

private:
    template <class... T, std::enable_if_t<(sizeof...(T) < N), void*> = nullptr>
    Foo(T... args)
    : Foo(args..., this)
    { }

    template <class... T, std::enable_if_t<(sizeof...(T) == N), void*> = nullptr>
    Foo(T... args)
    : _array{{args...}}
    { }  
like image 28
Barry Avatar answered Oct 23 '22 06:10

Barry