设置 class 成员 unique_ptr<T[]> 数组而不复制
Set class member unique_ptr<T[]> array without copying
我有一个 class,其中包含一个由 unique_ptr 管理的 C 风格数组。我想提供一个构造函数:
class A {
unique_ptr<T[]> p;
public:
A(int d, X x) : p(new T[d]) {
//Transfer from x to p without copying
}
}
这样我就可以用类似的东西构建我的对象:
int main(..) {
A a{n,{expr1,expr2,..}};
}
其中 {expr1,expr2,..} 包含初始化的值(在运行时计算)。由于这个列表是临时的,在我看来构建它是浪费资源,将它的值复制到实际对象中并丢弃它。
我相信有了移动语义、右值和 C++11 的所有优秀特性,应该有一个解决这个简单任务的方法,但我找不到它(我是 C++ 的新手)。
我想坚持使用 C 风格的数组,不要转向 std::vectors。有解决办法吗?
我想在这里提出两点。
AFAICS,与使用 std::vector<T>
的标准 C++ 解决方案相比,std::unique_ptr<T[]>
为您提供的好处微乎其微,即减少内存占用(容器占用 64 字节而不是 128 字节本身在 64 位机器上,也可能使用堆的数量),但请参阅讨论 here。任何 C++ 新手都应该坚持 std::vector
.
移动语义仅对在堆上管理内存的对象有益 ('free store')。因此,只有当您的 expr1
、expr2
等对象本身跟踪分配的内存时,移动才有意义。这里没有出现这种情况,所以直接复制。
可以,可以使用完美转发:
#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);
}
我有一个 class,其中包含一个由 unique_ptr 管理的 C 风格数组。我想提供一个构造函数:
class A {
unique_ptr<T[]> p;
public:
A(int d, X x) : p(new T[d]) {
//Transfer from x to p without copying
}
}
这样我就可以用类似的东西构建我的对象:
int main(..) {
A a{n,{expr1,expr2,..}};
}
其中 {expr1,expr2,..} 包含初始化的值(在运行时计算)。由于这个列表是临时的,在我看来构建它是浪费资源,将它的值复制到实际对象中并丢弃它。
我相信有了移动语义、右值和 C++11 的所有优秀特性,应该有一个解决这个简单任务的方法,但我找不到它(我是 C++ 的新手)。
我想坚持使用 C 风格的数组,不要转向 std::vectors。有解决办法吗?
我想在这里提出两点。
AFAICS,与使用
std::vector<T>
的标准 C++ 解决方案相比,std::unique_ptr<T[]>
为您提供的好处微乎其微,即减少内存占用(容器占用 64 字节而不是 128 字节本身在 64 位机器上,也可能使用堆的数量),但请参阅讨论 here。任何 C++ 新手都应该坚持std::vector
.移动语义仅对在堆上管理内存的对象有益 ('free store')。因此,只有当您的
expr1
、expr2
等对象本身跟踪分配的内存时,移动才有意义。这里没有出现这种情况,所以直接复制。
可以,可以使用完美转发:
#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);
}