设置类成员unique_ptr <t []>数组而不复制

时间:2017-05-25 20:53:33

标签: c++ move-semantics unique-ptr initializer-list rvalue

我有一个包含使用unique_ptr管理的c样式数组的类。我想提供一个构造函数:

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

这样我就可以用以下内容构建我的对象:

char    **ptr;

str = malloc(sizeof(char *) * 3); // Allocates enough memory for 3 char pointers
str[0] = malloc(sizeof(char) * 24);
str[1] = malloc(sizeof(char) * 25);
str[2] = malloc(sizeof(char) * 25);

其中{expr1,expr2,..}包含inizialization的值(在运行时计算)。由于这个列表是临时的,在我看来浪费资源来构建它,将其值复制到实际对象中并丢弃它。

我相信通过移动semantincs,rvalues和C ++ 11的所有优秀功能,应该有一个解决这个简单任务的方法,但我找不到它(我在C ++中很新)。 / p>

我想坚持使用c风格的数组,而不是转向std :: vectors。有解决方案吗?

2 个答案:

答案 0 :(得分:2)

我想在这里制作两个要点。

  1. AFAICS, Truck& operator=( Truck &x) { if( this != &x) { price=x.getPrice(); } return *this; } Truck operator=(Truck x) { if( this != &x) { price=x.getPrice(); } return *this; } 为使用std::unique_ptr<T[]>的标准C ++解决方案提供的好处很少,即内存占用减少(64位容器本身为64而不是128字节)机器以及可能还有堆的使用量),但请参阅讨论here。任何C ++新手都应该坚持std::vector<T>

  2. 移动语义只对管理堆上内存的对象有用(&#39; free store&#39;)。因此,只有当您的std::vectorexpr1等是自己跟踪已分配内存的对象时,移动才有意义。这不是这里的情况,所以只需复制。

答案 1 :(得分:2)

是的,您可以使用完美转发:

#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);
}