为什么标准c++ 11库中没有std::make_unique函数模板?我发现
std::unique_ptr<SomeUserDefinedType> p(new SomeUserDefinedType(1, 2, 3));
有点啰嗦。下面的不是更好吗?
auto p = std::make_unique<SomeUserDefinedType>(1, 2, 3);
这很好地隐藏了new,并且只提到了一次类型。
不管怎样,这是我对make_unique实现的尝试:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
我花了相当长的时间来获得std::forward的东西来编译,但我不确定它是否正确。是吗?std::forward<Args>(Args)…的意思吗?编译器对此做了什么?
在c++ 11中…(在模板代码中)也用于“包扩展”。
要求是将它用作包含未展开的参数包的表达式的后缀,并且它将简单地将表达式应用于包的每个元素。
例如,以你的例子为例:
std::forward<Args>(args)... -> std::forward<int>(1), std::forward<int>(2),
std::forward<int>(3)
std::forward<Args...>(args...) -> std::forward<int, int, int>(1,2,3)
我认为后者是不正确的。
另外,参数包不能传递给未展开的函数。我不确定一个模板参数包。
std::make_shared不仅仅是std::shared_ptr<Type> ptr(new Type(…));的简写。它能做一些没有它就做不到的事情。
为了完成它的工作,std::shared_ptr除了为实际指针保留存储空间外,还必须分配一个跟踪块。但是,因为std::make_shared分配的是实际对象,所以std::make_shared可能在同一个内存块中分配对象和跟踪块。
当std::shared_ptr<Type> ptr = new Type(…);将会有两个内存分配(一个分配给new,一个分配给std::shared_ptr跟踪块),std::make_shared<Type>(…)将分配一个内存块。
这对于std::shared_ptr的许多潜在用户来说很重要。std::make_unique能做的唯一一件事就是稍微方便一些。仅此而已。
很好,但是Stephan T. Lavavej(更广为人知的是STL)有一个更好的make_unique解决方案,它可以正确地用于数组版本。
#include <memory>
#include <type_traits>
#include <utility>
template <typename T, typename... Args>
std::unique_ptr<T> make_unique_helper(std::false_type, Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
template <typename T, typename... Args>
std::unique_ptr<T> make_unique_helper(std::true_type, Args&&... args) {
static_assert(std::extent<T>::value == 0,
"make_unique<T[N]>() is forbidden, please use make_unique<T[]>().");
typedef typename std::remove_extent<T>::type U;
return std::unique_ptr<T>(new U[sizeof...(Args)]{std::forward<Args>(args)...});
}
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return make_unique_helper<T>(std::is_array<T>(), std::forward<Args>(args)...);
}
这可以在他的Core c++ 6视频中看到。
STL的make_unique版本的更新版本现已作为N3656提供。这个版本被采纳到c++ 14草案中。