You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用initializer_list初始化指向数组的unique_ptr遇C2664编译错误

为啥用initializer_list初始化指向std::array的unique_ptr会报C2664错误?

哈哈,这个坑我之前也踩过!咱们一步步拆解来弄明白编译器为啥给你抛这个错误。

核心原因:std::array没有接受initializer_list的构造函数

你平时写std::array<int, 3> arr = {1, 2, 3};能成功,不是因为std::array有对应的构造函数,而是因为它是C++里的聚合类型——聚合类型可以直接用花括号做元素初始化,不需要专门的构造函数支持。

而当你尝试用std::make_unique<std::array<int,3>>({1,2,3})这类代码初始化unique_ptr时,std::make_unique会尝试把你传的initializer_list作为参数,去调用std::array的构造函数。但翻遍std::array的构造函数列表,你会发现它只有:

  • 默认构造函数
  • 拷贝构造函数
  • 移动构造函数

完全没有接受std::initializer_list的版本!

错误提示的由来

编译器找不到匹配的构造函数时,会尝试做隐式转换来“凑”出可行的调用——比如它会想:能不能把initializer_list转换成const std::array&,然后调用拷贝构造函数?但initializer_list和std::array是完全不同的类型,根本没有这种隐式转换路径,于是就抛出了C2664错误,告诉你没法把initializer_list转成const std::array&。

正确的初始化方式

给你两种靠谱的解决办法:

  • 方法一:先构造好std::array,再转移给unique_ptr

    std::array<int, 3> arr = {1, 2, 3};
    auto ptr = std::make_unique<std::array<int, 3>>(std::move(arr));
    

    用std::move避免不必要的拷贝,效率更高。

  • 方法二:直接new的时候用聚合初始化

    auto ptr = std::unique_ptr<std::array<int, 3>>(new std::array<int, 3>{1, 2, 3});
    

    这里直接在new的时候用花括号做聚合初始化构造std::array,再把指针传给unique_ptr的构造函数,完美绕开构造函数匹配的问题。

另外提一句:你查到的“可行”资料,大概率是把指向C风格数组的unique_ptr和指向std::array的unique_ptr搞混了——这俩是完全不同的场景,别搞混哦!

内容的提问来源于stack exchange,提问作者FirstProphet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:49:31