C++ 类似数组的类复制构造函数

C++ 类似数组的类复制构造函数,c++,arrays,c++11,C++,Arrays,C++11,我正在为GPU编写代码,所以我不能使用STL类,因为方法需要特殊的注释才能在GPU上运行。因此,我正在重新实现std::array,并在其方法上添加适当的注释(INLINE)。我现在遇到的问题是复制构造函数调用成员上的赋值运算符: template <typename T, Int n> class Few { T array_[n]; public: INLINE Few(Few<T, n> const& rhs) { for (Int i

我正在为GPU编写代码,所以我不能使用STL类,因为方法需要特殊的注释才能在GPU上运行。因此,我正在重新实现
std::array
,并在其方法上添加适当的注释(
INLINE
)。我现在遇到的问题是复制构造函数调用成员上的赋值运算符:

template <typename T, Int n>
class Few {
  T array_[n];

 public:
  INLINE Few(Few<T, n> const& rhs) {
    for (Int i = 0; i < n; ++i) array_[i] = rhs.array_[i];
  }
};
模板
少数班{
T数组_n;
公众:
内联少量(少量常量和右侧){
对于(Int i=0;i

对于simple
T
,这是可行的,但是有一种类型需要调用复制构造函数,而不是赋值运算符。如何让编译器复制数组中的每个元素?

似乎使用了已计算出的placement new运算符。我不确定这是完全合法的C++标准,但这里是:

  INLINE Few(Few<T, n> const& rhs) {
    for (Int i = 0; i < n; ++i) new (array_ + i) T (rhs.array_[i]);
  }
内联少量(少量常量和rhs){
对于(Int i=0;i
似乎使用了新算符的位置。我不确定这是完全合法的C++标准,但这里是:

  INLINE Few(Few<T, n> const& rhs) {
    for (Int i = 0; i < n; ++i) new (array_ + i) T (rhs.array_[i]);
  }
内联少量(少量常量和rhs){
对于(Int i=0;i
如何让编译器复制数组中的每个元素

它已经会了。这正是默认复制构造函数在这里要做的。所以不要自己提供,也不要显式默认:

Few(Few const& ) = default;
如何让编译器复制数组中的每个元素

它已经会了。这正是默认复制构造函数在这里要做的。所以不要自己提供,也不要显式默认:

Few(Few const& ) = default;


“行得通吗?”fun4jimmy说。它没有为GPU添加注释,但我复制了它的实现,这很有效。实际上数组已经默认初始化,所以使用未初始化的数组复制可能无效。@有趣有效,但通常不是个好主意。可以吗?@fun4jimmy差不多。它没有对GPU进行注释,但我复制了它的实现,这很有效。实际上数组已经默认初始化,所以使用未初始化的数组复制可能无效。@有趣有效,但通常是个坏主意。如果需要调用placement new,您可能还应该手动调用dtor。如果类型T的默认构造函数分配了一些内存,会发生什么?我认为在已经初始化的值上调用placement new会导致它泄漏?当且仅当您切换到
std::aligned_storage_t array时,此解决方案才是正确的
alignas(T)char数组[n*sizeof(T)]。如果您有
T数组[n]然后调用placement new是未定义的行为,因为编译器在之前调用相同对象上的默认构造函数。@HolyBlackCat它不是未定义的。您只需在其位置构造新对象,并在不运行析构函数的情况下结束旧对象的生命周期,这是允许的,只要您不依赖于这些析构函数的副作用。@HolyBlackCat[basic.life],尤其如此。如果您需要调用placement new,您可能还应该手动调用dtor。如果类型T的默认构造函数分配了一些内存,会发生什么?我认为在已经初始化的值上调用placement new会导致它泄漏?当且仅当您切换到
std::aligned_storage_t array时,此解决方案才是正确的
alignas(T)char数组[n*sizeof(T)]。如果您有
T数组[n]然后调用placement new是未定义的行为,因为编译器在之前调用相同对象上的默认构造函数。@HolyBlackCat它不是未定义的。您只需在其位置构造新对象,并在不运行析构函数的情况下结束旧对象的生命周期,这是允许的,只要您不依赖于这些析构函数的副作用。@HolyBlackCat[basic.life],尤其如此。这一切归结为GPU的
内联
注释。默认的复制构造没有那个注释,所以我需要一个显式的等价物。它可以归结为GPU的
INLINE
注释。默认的副本构造没有该注释,因此我需要一个显式的等效项。