Set class member unique_ptr <T []> array without copying

I have a class containing a c-style array managed with unique_ptr. I want to provide a constructor:

class A {
  unique_ptr<T[]> p;
public:
  A(int d, X x) : p(new T[d]) {
    //Transfer from x to p without copying
  }
}

      

so that I can build my object with something like:

int main(..) {
  A a{n,{expr1,expr2,..}};
}

      

where {expr1, expr2, ..} contains the values ​​(evaluated at runtime) to initialize. Since this list is temporary, it seems to me that it wastes resources in creating it by copying its values ​​into the actual object and discarding it.

I believe that with move semantincs, rvalues ​​and all the nice C ++ 11 features there should be a solution to this simple problem, but I haven't been able to find one (I'm completely new to C ++).

I would like to stick with c-style arrays and not go to std :: vectors. Is there a solution?

+3


source to share


2 answers


Yes, you can use perfect forwarding:



#include <memory>
#include <string>

struct S
{
    S(int) {}
    S(S const&) = delete;
    S(S&&) = default;
};

template<typename T>
struct A
{
    std::unique_ptr<T[]> p;

    template<typename... Args>
    A(int d, Args&&... args)
        : p(new T[sizeof...(args)]{std::forward<Args>(args)...})
    {
    }
};

int main()
{
    A<int> a(0, 1, 2, 3, 4);

    A<std::string> b(0, "hello", "world!", "\n");

    S s(0);
    A<S> c(0, std::move(s), 2, 3);
}

      

+2


source


There are towing points here.



  • AFAICS, std::unique_ptr<T[]>

    offers you very few advantages over the standard C ++ solution using std::vector<T>

    , namely reduced memory area (64 instead of 128 bytes for the container itself on a 64-bit machine and potentially also on the amount of heap used), but see the discussion here . Any newby in C ++ should stick std::vector

    .

  • Moving semantics is only useful for objects that manage memory on the heap ("free store"). Therefore, only if yours expr1

    , expr2

    etc. Are objects that themselves keep track of allocated memory, whether motion matters. It doesn't look like it here, so just copy.

+2


source







All Articles