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

Why make_unique and make_shared uses parenthesis and not curly braces?

即标准库的所有实现(在 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 的相同问题。)

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

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

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

#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。