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

时间:2018-02-07 12:49:26

标签: c++ shared-ptr smart-pointers 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)...));
}

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

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的相同问题。)

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分: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";
}

此处a是尺寸为12的vectorb是尺寸为1的vector,其值为12.