`auto x = {1,2,3};`的自动类型检测

问题描述 投票:0回答:1

传统上,人们从左到右阅读变量声明/定义,例如:

std::vector<float> arr = {3.14, 1.414, 2.71, -0.2};

所以

{3.14, 1.414, 2.71, -0.2}
的含义就很清楚了:我们有一个
std::vector<float>
类型变量
arr
,我们想用四个元素来初始化它:3.14、1.414、2.71、-0.2

但是

auto
的引入让这变得更加晦涩难懂。下面的
auto
关键字有什么作用?:

auto arr = {3.14, 1.414, 2.71, -0.2};

我的 clangd 提示这里的 arr 是:

std::initializer_list<double>
,这是所有标准兼容编译器中唯一的类型推导结果还是某些编译器可以在这里自由地将 auto arr 设为
std::vector<double>

一个更详细和复杂的示例:,我有一个模板函数,可以从正好三个

std::vector
中获取最大值:

template <typename T>
constexpr T getMax(const std::vector<T> &v1, const std::vector<T> &v2, const std::vector<T> &v3)
{
    auto arr = { std::views::all(v1), std::views::all(v2), std::views::all(v3)};
    auto view = std::views::join(arr);
    return std::ranges::max(view);
}

在此代码片段中,我们定义了一个

auto arr
变量:

auto arr = { std::views::all(v1), std::views::all(v2), std::views::all(v3)};

它从 gcc 推导的类型是:

std::initializer_list<std::ranges::ref_view<std::vector<std::string_view>>>
,什么要求编译器必须将
auto
类型推导为这个冗长的具体类型?这个结果是唯一的还是每个编译器只要遵循一些规则就可以自由地进行自己的推论?

c++ auto
1个回答
0
投票

它应该始终是

std::initializer_list

[dcl.type.auto.deduct]/3

如果初始化是复制列表初始化,则声明 std::initializer_list 应先于 ([basic.lookup.general]) 占位符类型说明符。

[示例1:

auto x1 = { 1, 2 };             // decltype(x1) is std​::​initializer_list<int>
auto x2 = { 1, 2.0 };           // error: cannot deduce element type
auto x3{ 1, 2 };                // error: not a single element
auto x4 = { 3 };                // decltype(x4) is std​::​initializer_list<int>
auto x5{ 3 };                   // decltype(x5) is int

—结束示例]

© www.soinside.com 2019 - 2024. All rights reserved.