2016-04-25 69 views
5

我想初始化对象的模板大小的数组没有默认的构造函数,如以下的代码:如何初始化模板大小的数组?

#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; 
} 

它是一个方式说:“我想要N个对象的数组,所有与此初始化相同的参数“?我认为模板元编程有一种方法,但我不知道如何去做。

+0

不应该是Bar的构造函数是Bar(Foo &super):_super(super)'?或者成员'Foo &_super'应该是'Foo * _super'? – wally

+0

@flatmouse不会改变任何东西,不是吗?我可以编写它并构建Bar,如下所示:Bar(* this)';但这并不能解决问题。 – Boiethios

+0

好吧,你正在接受一个指针,然后它被引用来初始化引用成员。我试图理解。我现在明白了。 – wally

回答

2

你能不能多增加一个this在同一时间,直到你有他们的N,在这一点上,你只是初始化_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...}} 
    { } 
+0

@Boiethios'index_sequence'方法更好。 – Barry

+0

是否可以在C++ 11中编写此代码('enable_if_t'是C++ 14)?例如,模板参数'size_t I'会减少,而一个专门的版本'<0>'?我尝试这样做,但是我在编写模板时遇到了麻烦。 – Boiethios

+0

@Boiethios'enable_if_t'只是一个别名模板,你可以复制C++ 11中的定义。 – Barry

9

一切皆有可能从make_index_sequence小的帮助:

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

请注意_array构造函数中的逗号运算符(,) - 礼貌@Quentin(与函数调用相反)。

+4

你可以用一个逗号操作符替换函数调用:'_array {(I,this)...}':) – Quentin

+0

@Quentin,很好!如果你不介意,将纳入。 – SergeyA

+0

当然!我不想发布与你的相同的答案,除了这个调整。 – Quentin