独特和完美的转发

为什么标准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东西来编译,但我不确定它是否正确。 是吗? std::forward<Args>(args)...意味着什么? 编译器对此做了什么?


Herb Sutter,C ++标准化委员会主席在他的博客上写道:

C ++ 11不包括make_unique部分是一个疏忽,将来几乎肯定会添加它。

他还给出了与OP给出的相同的实现。

编辑:现在std::make_unique是C ++ 14的一部分。


不错,但是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视频中看到。

N3656现在提供STL版本的make_unique的更新版本。 该版本已被采纳为草案C ++ 14。


尽管没有什么能够阻止你编写自己的帮助器,但我相信在库中提供make_shared<T>主要原因是它实际上创建了一个不同于shared_ptr<T>(new T)内部类型的共享指针,这是不同的如果没有专门的帮手,就无法实现这一点。

另一方面,你的make_unique包装仅仅是一个new表达式的语法糖,所以虽然它看起来很令人愉快,但它并没有带来任何new的东西。 更正:事实上并非如此:有一个函数调用来包装new表达式会提供异常安全性,例如在调用函数void f(std::unique_ptr<A> &&, std::unique_ptr<B> &&) 。 拥有两个相互不相关的原始new意味着如果一个新的表达式失败并产生异常,另一个可能会泄漏资源。 至于为什么标准中没有make_unique :它只是被遗忘了。 (偶尔会发生这种情况,即使应该有一个,标准中也没有全局的std::cbegin 。)

另请注意, unique_ptr需要第二个模板参数,您应该以某种方式允许; 这与shared_ptr不同,它使用类型擦除来存储自定义删除程序,而不使其成为类型的一部分。

链接地址: http://www.djcxy.com/p/78709.html

上一篇: unique and perfect forwarding

下一篇: initial value of int array in C