c++ - 带有大括号初始化的 make_unique

标签 c++ initialization c++14 unique-ptr c++-standard-library

https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique写道 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)...));
}

这不适用于没有构造函数的普通结构。这些可以用大括号初始化,但没有非默认构造函数。示例:

#include <memory>
struct point { int x, z; };
int main() { std::make_unique<point>(1, 2); }

Compiling this将使编译器提示缺少 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)...});
}

那个works well enough对于上面的场景。是否还有任何其他合法用例会被破坏?

看到一般趋势似乎更喜欢用大括号进行初始化,我认为在该模板中制作大括号是规范的选择,但标准不这样做的事实可能表明我遗漏了一些东西。

最佳答案

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

std::make_unique<point>(1, 2);

由于新规则allowing initializing aggregates from a parenthesized list of values .


在 C++17 中,你可以这样做:

std::unique_ptr<point>(new point{1, 2});

虽然这不适用于 make_shared。所以你也可以只创建一个工厂(作为练习向左转发):

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));

在 C++14 中,您必须实现 apply 并为 braced_init 编写一个工厂函数,因为还没有 CTAD - 但这些都是可行的。


Seeing how the general trend appears to prefer braces for initialization

需要引用。这是一个充满争议的话题——但我绝对不同意这种说法。

关于c++ - 带有大括号初始化的 make_unique,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55141594/

相关文章:

c++ - OpenCV 中颜色差异的简单度量?

c++ - 带星号和符号的函数参数

c++ - 我在哪个时区初始化 QDateTime?

java - 从 .properties 文件为 JUnit 初始化一个常量,该文件本身是从 pom.xml 文件初始化的

arrays - 将数组初始化为固定长度数组的最佳方法是什么? (C++/CLI)

c++ - 在模板参数列表中使用 sizeof... 时为 "too few template arguments"(MSVC 2017)

c++ - 为什么通过 const 引用传递 constexpr 对象有效,但按值不编译

c++ - 迭代 vector/ map 数据结构 C++

iOS alloc popover Controller 导致崩溃

c++ - 我可以隐式创建一个可简单复制的类型吗