即。标准库的所有实现(在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
的相同问题。)
答案 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的vector
,b
是尺寸为1的vector
,其值为12.