1

I'm writing code for GPUs, so I can't use STL classes because methods need special annotations to run on the GPU. So, I'm reimplementing std::array, with proper annotations (INLINE) on its methods. The issue I have right now is my copy constructor calls the assignment operator on members:

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

That works okay for simple T, but there is a type for which this needs to call the copy constructor, not the assignment operator. How do I get the compiler to copy construct each element in the array ?

4
  • Would std::uninitialized_copy_n work? Commented Dec 4, 2016 at 18:05
  • @fun4jimmy almost. its not annotated for GPUs, but I copied its implementation and that worked. Commented Dec 4, 2016 at 18:08
  • 2
    Actually array_ has been default initialised already so it's probably not valid to use uninitialized_copy_n. Commented Dec 4, 2016 at 18:08
  • 1
    @fun valid, but usually a bad idea. Commented Dec 4, 2016 at 19:02

2 Answers 2

8

How do I get the compiler to copy construct each element in the array ?

It already will. That's exactly what the default copy constructor will do here. So just don't provide one yourself, or explicitly default it:

Few(Few const& ) = default;
Sign up to request clarification or add additional context in comments.

1 Comment

it all comes down to that INLINE annotation for GPUs. the default copy construction doesn't have that annotation, so I needed an explicit equivalent.
-3

It seems like using the placement-new operator worked out. I'm not sure this is completely legit per the C++ standard, but here it is:

  INLINE Few(Few<T, n> const& rhs) {
    for (Int i = 0; i < n; ++i) new (array_ + i) T (rhs.array_[i]);
  }

7 Comments

Iff you need to call placement-new, you probably also should call the dtor manually.
What happens if type T's default constructor allocates some memory? I think calling placement new on an already initialised value would cause it to leak?
This solution is correct if and only if you switch to std::aligned_storage_t<T[n]> array; or alignas(T) char array[n * sizeof(T)];. If you have T array[n]; then calling placement new is undefined behavior becaue the compiler calls default constructors on the same objects just before.
@HolyBlackCat It's not undefined. You just construct new objects in their place and end the lifetime of the old ones without running their destructors, which is allowed as long as you don't depend on those destructors' side effects.
@HolyBlackCat [basic.life], in particular /5.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.