为什么make_unique和make_shared使用括号而不是花括号?

vla*_*don 2 c++ smart-pointers shared-ptr unique-ptr

即标准库的所有实现(在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)...));
}
Run Code Online (Sandbox Code Playgroud)

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

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
}
Run Code Online (Sandbox Code Playgroud)

(同样的问题make_shared.)

Som*_*ude 5

因为花括号根据T它定义的内容和构造函数做了不同的事情.

如果T有一个构造函数接受一个std::initializer_list参数,那么在使用花括号时将调用该构造函数.这不是真正的意图.

  • 除非它是需要的,在这种情况下你可以自己提供括号,如`std :: make_unique <std :: vector <int >>({2,3})` (2认同)

lll*_*lll 5

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

#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";
}
Run Code Online (Sandbox Code Playgroud)

这里a是一个vector大小为12的,b是一个vector大小为1,其值是12.