Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用大括号初始化使_唯一_C++_Initialization_C++14_Unique Ptr_C++ Standard Library - Fatal编程技术网

C++ 使用大括号初始化使_唯一

C++ 使用大括号初始化使_唯一,c++,initialization,c++14,unique-ptr,c++-standard-library,C++,Initialization,C++14,Unique Ptr,C++ Standard Library,写入std::make_unique可以实现为 template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } 模板 std::unique_ptr使_唯一(Args&&…Args)

写入
std::make_unique
可以实现为

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
模板
std::unique_ptr使_唯一(Args&&…Args)
{
return std::unique_ptr(新的T(std::forward)会让编译器抱怨缺少2参数构造函数,这是正确的

我想知道,有没有什么技术上的理由不使用括号初始化来定义函数呢

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
}
模板
std::unique_ptr使_唯一(Args&&…Args)
{
返回std::unique_ptr(针对上述场景的新T{std::forward)。是否有其他合法的用例会被打破


鉴于一般趋势似乎更倾向于使用大括号进行初始化,我认为在该模板中使用大括号将是一种规范选择,但标准没有这样做这一事实可能表明我遗漏了一些东西。

一些类在这两种初始化样式中有不同的行为。例如

std::vector<int> v1(1, 2); // 1 element with value 2
std::vector<int> v2{1, 2}; // 2 elements with value 1 & 2
std::vector v1(1,2);//值为2的1个元素
std::vector v2{1,2};//2个值为1和2的元素
可能没有足够的理由选择一个而不是另一个;我认为标准只是选择一个并明确说明决定


作为解决方法,您可能希望实现自己的
make_unique
版本。如您所示,这不是一项艰苦的工作。

在C++20中,这将编译:

std::make_unique<point>(1, 2);
在C++14中,您必须实现
apply
并为
bracked_init
编写一个工厂函数,因为还没有CTAD,但这些都是可行的



看看总体趋势是如何倾向于使用大括号进行初始化的


需要引用。这是一个收费的话题-但我绝对不同意这种说法。

除了其他答案之外,在他关于C++17的著作中,Alisdair Meredith给出了
make_unique
的以下实现:

模板
自动使_唯一(Args&&…Args)->std::unique_ptr{
如果constexpr(std::is_constructible::value)
返回std::unique_ptr(新的T(std::forward(args)…);
其他的
返回std::unique_ptr(新的T{std::forward(args)…});
}
如果constexpr
,它将使用C+17
,但在没有它的情况下很容易重写

使用此版本,您可以同时执行这两项操作

auto v = make_unique<std::vector<int>>(10, 20); // *v is a vector of 10 elements
auto v=make_unique(10,20);//*v是由10个元素组成的向量

auto p=make_unique(10,20);//*p是一个点(10,20)

当您调用
make_unique(10,20)
您想得到什么?包含10项的向量、所有20个值(当()用于make_unique时)或包含2项的向量10,20(当使用{}时,向量具有采用初始值设定项列表的构造函数)如果有任何安慰,就有管道。C++的未来版本可以支持聚合,而不需要改变工厂库函数如何工作。尽管可以想象,在今天的代码< STD::ISSGu骨舞会特性的帮助下,可以支持这样的东西。我猜人们觉得最好是这样。这是一个语言解决方案,而不是库解决方案。“看看总体趋势如何倾向于使用大括号进行初始化”我担心由于向量等的问题,现在已经没有这种趋势了。从开始,它是为了匹配
make\u shared
。我还没有找到
make\u shared
为什么选择一种方式而不是另一种。
shared\u ptr
在TR1中,但在统一初始化语法存在之前很久-不确定
make\u shared
是否存在当时。我相信C++20改变了这个答案。不,C++20不会从答案中破坏任何东西。std::vector构造函数的两个版本仍然不同,make_shared仍然会调用圆括号构造函数(委员会永远不会支持破坏大量代码的更改)。但是,C++20将允许使用标准大括号进行聚合初始化。括号内的初始化也有自己的守护进程。如果此初始化器类执行非大括号的直接初始化,则会更加复杂。使用C++20,这仍然不会编译:
auto p=std::make_unique(1,2)std::unique_ptr<point>(new point{1, 2});
template <typename... Args>
struct braced_init {
    braced_init(Args... args) : args(args...) { }
    std::tuple<Args...> args;

    template <typename T>
    operator T() const {
        return std::apply([](Args... args){
            return T{args...};
        }, args);
    }
};

std::make_unique<point>(braced_init(1, 2));
auto v = make_unique<std::vector<int>>(10, 20); // *v is a vector of 10 elements
auto p = make_unique<point>(10, 20); // *p is a point (10, 20)