【问题标题】:Why make_unique and make_shared uses parenthesis and not curly braces?为什么 make_unique 和 make_shared 使用括号而不是花括号?
【发布时间】:2018-02-07 12:49:26
【问题描述】:

即标准库的所有实现(在 MSVC、clang、gcc 中)都使用以下代码(为了便于阅读而进行了简化):

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

但是为什么不用花括号呢?即:

template<class T, class... Args>
inline unique_ptr<T> make_unique(Args&&... args)
{
    return unique_ptr<T>(new T{std::forward<Args>(args)...});
    //                        ^ here and                  ^ here
}

make_shared 的问题相同。)

【问题讨论】:

    标签: c++ shared-ptr smart-pointers unique-ptr


    【解决方案1】:

    因为这两种实现在某些情况下会表现不同。标准库必须选择其中一种语义以使其保持一致。

    #include <memory>
    #include <vector>
    #include <iostream>
    
    template<class T, class... Args>
    inline std::unique_ptr<T> my_make_unique(Args&&... args)
    {
        return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
    }
    
    int main() {
        auto a = std::make_unique<std::vector<int>>(12);
        std::cout << a->size() << "\n";
    
        auto b = my_make_unique<std::vector<int>>(12);
        std::cout << b->size() << "\n";
    }
    

    这里a 是大小为12 的vectorb 是大小为1 的vector,其值为12。

    【讨论】:

      【解决方案2】:

      因为花括号会根据 T 是什么以及它定义的构造函数做不同的事情。

      如果T 的构造函数采用std::initializer_list 参数,则在使用花括号时将调用该构造函数。这并不是真正的意图。

      【讨论】:

      • 除非需要,您可以自己提供牙套,如std::make_unique&lt;std::vector&lt;int&gt;&gt;({2,3})
      • @aschepler:除了它不会编译为{2, 3}不会被推导出来......
      • 我相信这个答案是正确的。我记得在某处阅读过关于构造 std::vector 时关于此类方法问题的讨论
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多