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?
source to share
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);
}
source to share
There are towing points here.
-
AFAICS,
std::unique_ptr<T[]>
offers you very few advantages over the standard C ++ solution usingstd::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 stickstd::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.
source to share