具有统一初始化语法的自动类型推导 c++11 vs c++17

auto type deduction with uniform initialisation syntax c++11 vs c++17

我正在尝试测试自动类型推导。 Scott Meyers(Effective modern C++)和 Bjarne Stroustrup 的 C++ Programming Language 都提到做

auto val {10};

将推断 val 为“初始化列表”类型。

我读到这在 C++17 中已更改,因此如果列表中只有一个元素,则 auto 将推导出该元素的一种类型。

但是,我通过明确指定 C++11 标准使用最新的 gcc (v10) 和 clang (V11) 编译器对此进行了测试,但我没有看到预期的行为

auto A {1.0};
std::cout << typeid(A).name();

在屏幕上打印“d”

auto A={1.0};
std::cout << typeid(A).name();

在屏幕上打印“St16initializer_listIdE”。

这个不管我是不是specity都一样

gcc -std=c++11

gcc -std=c++17

对于 clang 也是如此。

我知道它在 C++17 中发生了变化,但为什么我看不到“旧”行为?还是我理解错了?

谢谢

auto A { 1.0 };

你有 direct initialization,将使用封闭表达式的类型推导类型。

本质上等同于

auto A = 1.0;

另一方面

auto A = { 1.0 };

copy list initialization,当与auto一起使用时:

A special exception is made for type deduction using the keyword auto, which deduces any braced-init-list as std::initializer_list in copy-list-initialization.

为 C++17 引入此更改的论文——https://wg21.link/n3922——声明如下:

Direction from EWG is that we consider this a defect in C++14.

如果某处存在缺陷,则意味着该文件已被追溯应用,因此未来针对先前标准编译的编译器将表现出 new 行为。这就是您看不到旧行为的原因。

如果您使用修复此缺陷之前的旧版编译器进行编译,您会看到推导类型为 std::initializer_list<double>: https://godbolt.org/z/GrnrTE 。 而如果将编译器更改为更新版本(例如 g++ 10.2),则可以看到推导类型为 doublehttps://godbolt.org/z/r5G945