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

为何在该场景下需显式指定默认构造对象的类型?

问题:为何foobar返回tuple时第二个元素必须显式指定std::vector<int>{},而foobar2可直接用{}?

代码示例

#include <iostream>
#include <memory>
#include <vector>
#include <tuple>

std::tuple<std::unique_ptr<int>, std::vector<int>> foobar() {
    std::unique_ptr<int> test = std::make_unique<int>(42);
    return { std::move(test), {} };    // <= 语法错误
    // return { std::move(test), std::vector<int>{} }  // <= 编译通过
}

std::tuple<int, std::vector<int>> foobar2() {
    return { {},  {} };  // 编译正常
}

int main() {
    std::cout << *std::get<0>(foobar()) << "\n";
    std::cout << std::get<0>(foobar2()) << "\n";
    return 0;
}

GCC编译错误信息

<source>: In function 'std::tuple<std::unique_ptr<int, std::default_delete<int> >, std::vector<int, std::allocator<int> > > foobar()':
<source>:8:34: error: could not convert '{std::move<unique_ptr<int>&>(test), <brace-enclosed initializer list>()}' from '<brace-enclosed initializer list>' to 'std::tuple<std::unique_ptr<int, std::default_delete<int> >, std::vector<int, std::allocator<int> > >'
    8 |     return { std::move(test), {} };    // <= 语法错误
      |                                  ^
      |                                  |
      |                                  <brace-enclosed initializer list>
Compiler returned: 1

原因解析

核心问题在于C++列表初始化的类型推导规则,以及std::tuple构造函数的匹配逻辑:

  1. foobar2能正常编译的原因
    foobar2返回的tuple元素类型是int和std::vector<int>:

    • 第一个{}会被隐式初始化为int类型的0;
    • 第二个{}会被隐式初始化为空的std::vector<int>;
      编译器可以明确将这两个空列表匹配到tuple对应元素的类型,顺利完成构造。
  2. foobar编译失败的原因
    foobar返回的tuple第一个元素是std::unique_ptr<int>,这是一个具有特殊构造规则的智能指针类型:

    • 当你写{ std::move(test), {} }时,第二个元素是未指定具体类型的空初始化列表(braced-init-list);
    • 由于第一个元素是std::unique_ptr,编译器在匹配std::tuple的构造函数时,无法推导这个空列表应该转换为std::vector<int>——空初始化列表本身没有类型,而std::unique_ptr的存在让编译器无法确定唯一的构造函数重载候选;
    • 必须显式写出std::vector<int>{},给编译器明确的类型提示,才能让它正确匹配tuple的构造,完成两个元素的初始化。

替代写法

除了显式指定std::vector<int>{},也可以用std::make_tuple来避免列表初始化的推导问题:

return std::make_tuple(std::move(test), std::vector<int>{});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:13:10