C++11:auto如何处理()初始化器?

C++11: how does auto deal with () initializer?

我知道 C++11 使用 auto 初始化 vector 的方法,实际上初始化 std::initializer_list 而不是 vector。 但是,下面给出了一段代码:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    auto x = {1, 2};
    cout << typeid(x).name() << endl;
    auto z = (1, 2);
    cout << z << ", type: " << typeid(z).name() << endl;
    return 0;
}

我不明白:

  1. 为什么xreturned的类型是St16initializer_listIiE而'z'returned的类型是'i',使用gcc -10 编译器。我们不应该只是 return std::initializer_list 和 'int' 吗?
  2. z 上有一个警告:warning: left operand of comma operator has no effect [-Wunused-value]。那么结果的第二半是:2, type: i。 c++11如何解释()-初始化类型?为什么只有最后一个元素传入 z,因此 z 仍然是 int 类型?

唯一构成初始化列表的是{}。在

auto z = (1, 2);

您拥有的是逗号运算符,它仅 returns 最后一个值。所以这意味着您的代码归结为

auto z = 2;

并且由于 2intzint

  1. 因为 { 1, 2 } 是一个 std::initializer_list<int>,但是 (1, 2) 是一个表达式,它扩展为逗号运算符(它计算参数和 returns 结果是第二个,所以 (1, 2) 被折叠成 (2)(2) 被折叠成 2。这就是为什么 auto z = (1, 2); 评估为整数初始化的原因。

  2. 因为指令 1 的结果被简单地忽略了(记住 (1, 2) 计算了两个表达式并丢弃了第一个的结果)。

Why the type of x returned is St16initializer_listIiE and the type of 'z' returned is 'i', using gcc-10 compiler. Shouldn't we just return std::initializer_list and 'int'?

typeid() 不会直接给出您所期望的,它只是 returns 代码中写下的特定类型标识。如果您想解密相同的内容,请通过 c++filt 传递:

c++filt -t St16initializer_listIiE

它将产生您所期望的结果,即:

std::initializer_list<int>

There is a warning on z: warning: left operand of comma operator has no effect [-Wunused-value]. Then the 2nd half of result is: 2, type: i. How does c++11 interpret ()-initialized type? Why is only the last element passed into z and thus z is still of type int?

( ) 是一个包含表达式或表达式列表的初始值设定项。如果您将其分配给 auto,它将 select 表达式列表中的最后一项作为其类型,因为它将用逗号分隔直到最后一个表达式出现,理想情况下告诉 auto将其类型分配给最后一个。

例如:

auto x = (1, 1.5L); 

会导致很长。

auto x = (1, 1.5f);

会导致浮动。

auto x = (1, "string");

会产生一个 const char 指针。

它完全忽略了 ( ) 初始化器中的第一个值,即 int.