使用"this"指针初始化 std::array

initialize std::array with 'this' pointer

本文关键字:std array 指针 this 使用 初始化      更新时间:2023-10-16

我试图在模板类中初始化数组,并将this指针传递给数组中的所有元素。这就是我的班级的样子:

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中)?

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

将委托构造函数与std一起使用::*_序列内容:

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,因为它们不修改您的会员。
  • cl[NUM - 1].print_num();您可能要使用std::array::back()

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

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的第一个模板参数,因为将其他T推断为outer_class<NUM>*,并且虽然从outer_class<NUM>*inner_class<NUM>的隐含转换,但从std::array<outer_class<NUM*>, NUM>转换为CC_18;
  • li>如果您使用的是C 11,而不是14或clang,则可能会在copy_nreturn上发出警告,您可以通过添加一对额外的支架{}来摆脱它。