【问题标题】:How to implement make_unique function in C++11? [duplicate]如何在 C++11 中实现 make_unique 函数? [复制]
【发布时间】:2013-07-27 23:11:13
【问题描述】:

我的编译器不支持 make_unique。一个怎么写?

template< class T, class... Args > unique_ptr<T> make_unique( Args&&... args );

【问题讨论】:

标签: c++ c++11 unique-ptr c++14


【解决方案1】:

Stephan T. Lavavej(也称为 STL)的版本,他最初提议将此函数添加到 C++14 中

#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>

namespace std {
    template<class T> struct _Unique_if {
        typedef unique_ptr<T> _Single_object;
    };

    template<class T> struct _Unique_if<T[]> {
        typedef unique_ptr<T[]> _Unknown_bound;
    };

    template<class T, size_t N> struct _Unique_if<T[N]> {
        typedef void _Known_bound;
    };

    template<class T, class... Args>
        typename _Unique_if<T>::_Single_object
        make_unique(Args&&... args) {
            return unique_ptr<T>(new T(std::forward<Args>(args)...));
        }

    template<class T>
        typename _Unique_if<T>::_Unknown_bound
        make_unique(size_t n) {
            typedef typename remove_extent<T>::type U;
            return unique_ptr<T>(new U[n]());
        }

    template<class T, class... Args>
        typename _Unique_if<T>::_Known_bound
        make_unique(Args&&...) = delete;
}

编辑:将代码更新为N3656 标准修订版

【讨论】:

  • @BenJackson 当make_unique 被正确使用时,意图是永远不会匹配_Known_bound 版本。如果有人尝试将其用作make_unique&lt;T[N]&gt;(),它将匹配_Known_bound 版本并导致错误。
  • 有什么好的方法可以将此定义包含在 C++ 代码中,最终可能在 stdc++ 中提供 make_unique 的环境中编译?
  • @AndreasYankopolus 我建议 #if __cplusplus == 201103L ... #endif (请参阅 gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html 末尾附近的 __cplusplus 条目)
  • 请注意,我们不允许像这样将东西放入 std:: 中。如果必须添加 make_unique,我宁愿使用自己的实用程序命名空间。
  • 您可以检查 __cplusplus 版本以避免出现问题。
【解决方案2】:

复制自make_unique and perfect forwardingHerb Sutter's blog中给出相同)

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

如果你在 VC2012 中需要它,请参阅Is there a way to write make_unique() in VS2012?


不过,如果sasha.sochka's answer 中的解决方案可以使用您的编译器编译,我会选择那个。这更精细,也适用于数组。

【讨论】:

  • 为什么点在 args 括号外?这对我来说太违反直觉了!
  • @Apollys 如果我正确理解您的问题:这会将参数扩展到std::forward,而不是T。 (也许我误解了你的问题。)
  • 可能这就是我要问的,我对... 语法知之甚少,只知道我在示例中看到的。我觉得奇怪的是,在std::forward&lt;Args&gt;(args)... 行中,args 现在似乎以某种方式单独表示每个参数,而在顶部它表示所有参数作为一个单元。
  • @Apollys 是的,C++ 是一种奇怪的语言,充满了这样的怪癖。 :(
  • 这在调用make_unique 来创建像unsigned char[] 这样的数组类型时不起作用并产生错误消息Allocation of incomplete type
猜你喜欢
  • 2011-11-24
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-17
  • 2011-12-12
  • 2012-04-09
  • 2012-08-24
相关资源
最近更新 更多