2017-08-29 82 views
3

我试图初始化模板类中的数组,并将this指针传递给数组中的所有元素。 这是我的课是什么样子:使用'this'指针初始化std :: array

template<int NUM> class outer_class; 

template<int N> 
class inner_class { 
    private: 
    outer_class<N> *cl; 
    public: 
    inner_class(outer_class<N> *num) { 
    cl = num; 
    } 
    void print_num() { 
    cl->print_num(); 
    } 

}; 

template<int NUM> class outer_class { 
private: 
    int number = NUM; 

    // --> here I basically want NUM times 'this' <-- 
    std::array<inner_class<NUM>, NUM> cl = { this, this, this, this }; 

public: 

    void print_num() { 
    std::cout << number << std::endl; 
    } 

    void print() { 
    cl[NUM - 1].print_num(); 
    } 
}; 

int main() { 
    outer_class<4> t; 
    t.print(); 

    return 0; 
} 

我怎样才能通过this指针存储的outer_class阵列中的所有inner_class元素(在C++ 11)?

回答

9

首先,在构造函数或任何其他成员函数之外不能有这样的this。在这里你必须在初始化列表中初始化cl

std::*_sequence东西一起使用delegating constructor

template<int NUM> class outer_class { 
    ... 

    template <std::size_t... Integers> 
    outer_class(std::index_sequence<Integers...>) 
    : cl{(static_cast<void>(Integers), this)...} 
    {} 

public: 
    outer_class(/* whatever */) : outer_class(std::make_index_sequence<NUM>{}) {} 
}; 

旁注:

  • print成员函数应标明const,因为它们不修改您的会员。您可能需要使用std::array::back()
+1

如果序列构造函数是私有的,会不会更好? – Rakete1111

+0

@ Rakete1111对,编辑。 –

+0

@奥尼尔Thx为您的答案,很好,很容易 –

4

你可以使用一些辅助功能,然后使用这些功能,如初始化成员:

template <std::size_t I, class T> 
T copy(T t) { return t; } 

template <class T, std::size_t... Is> 
constexpr std::array<T, sizeof...(Is)> copy_n(T const& t, std::index_sequence<Is...>) { 
    return {copy<Is>(t)... }; 
} 

template <class T, std::size_t N> 
constexpr std::array<T, N> copy_n(T const& t) { 
    return copy_n(t, std::make_index_sequence<N>{}); 
} 
在类

然后:

std::array<inner_class<NUM>, NUM> cl; 

outer_class() : cl(copy_n<inner_class<NUM>, NUM>(this)) { } 

注:

  • [待验证]您不能在默认会员中使用this初始化器,所以你需要有一个自定义的构造函数;
  • 你需要明确指定inner_class<NUM>copy_n第一个模板参数,因为otherwize T会推导出outer_class<NUM>*,虽然有来自outer_class<NUM>*inner_class<NUM>的隐式转换,从没有std::array<outer_class<NUM*>, NUM>std::array<inner_class<NUM>, NUM>转换;
  • 如果您使用C++ 11而非14或clang,则可能会在returncopy_n上发出警告,您可以通过添加一对额外的括号{}来消除它。
+0

@Someprogrammerdude谢谢,我真的很想知道,但没有找到自己的信息...将更新答案。 – Holt

+1

或者它可以吗? [似乎工作正常](http://coliru.stacked-crooked.com/a/9c9adcb807cfa68a)。 –

+0

这看起来不错,但是有一个std :: make_index_sequence的C++ 11兼容版本吗? –