C++ 为什么在初始化映射时不能忽略大括号?

C++ 为什么在初始化映射时不能忽略大括号?,c++,c++11,initializer-list,C++,C++11,Initializer List,受此启发,我尝试了下一个例子: #include <map> #include <string> #include <iostream> int main() { const std::map< int, std::string > mapping = { 1, "ONE", 2, "TWO", }; const auto it = mapping.find( 1 ); if ( mapping.en

受此启发,我尝试了下一个例子:

#include <map>
#include <string>
#include <iostream>

int main()
{
  const std::map< int, std::string > mapping = {
      1, "ONE",
      2, "TWO",
    };

  const auto it = mapping.find( 1 );
  if ( mapping.end() != it )
  {
    std::cout << it->second << std::endl;
  }
  else
  {
    std::cout << "not found!" << std::endl;
  }
}
#包括
#包括
#包括
int main()
{
常量std::mapmap={
一,"一",,
二,"两个",,
};
const auto it=mapping.find(1);
if(mapping.end()!=it)
{
std::cout second映射={
{1,“一”},
{2,“两”},
};

但是为什么在上面的示例中编译失败呢?

因为映射是非聚合的,并且包含非聚合元素(
std::pair
),所以它需要一个初始值设定项列表,每个初始值设定项列表对应一个初始值设定项列表

std::pair<int,int> p0{ 1,2 }; // single pair
std::map<int, int> m { { 1,2 } }; // map with one element
std::map<int, int> m { { 1,2 }, { 3,4} }; // map with two elements
std::pair p0{1,2};//单对
std::map m{{1,2}};//带有一个元素的map
std::map m{{1,2},{3,4};//具有两个元素的map

记住,括号的规则适用于聚合,所以它们不适用于这里。

我已经做了很长时间C++了,但是我猜是因为 STD::MAP< /Cord>期望一组单独的对象,每个对象包含一个键和一对值。


只有一个单独的项目列表是没有意义的,而且也很难阅读(以确保有许多项目可以被二整除)。

C++11标准仅允许在目标为聚合时省略大括号:

8.5.1骨料[dcl.初始骨料]

聚合是没有提供用户的数组或类(第9条) 构造函数(12.1),无大括号或同等值-非静态的初始值设定项 数据成员(9.2),无私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)

(第11段)

以声明的形式

T x = { a };
大括号可以在初始值设定项列表中省略,如下所示 初始值设定项列表以左大括号开始,随后是 以逗号分隔的初始化器子句列表初始化 亚集合体;有更多的是错误的 初始值设定项子句多于成员。但是,如果初始值设定项列表 对于子集合,它不是以左大括号开始,而是仅以左大括号开始 从列表中选取足够的初始值设定项子句来初始化 子集合的成员;任何剩余的初始值设定项子句 左键初始化聚合的下一个成员,其中 当前子集合是一个成员


std::pair
是一个聚合,因此它本身不需要一个初始化列表(就像在中解释的那样)。或者,我错了吗?@B实际上,
std::pair
不是聚合。我不知道
{}的规则
可以省略,但在这种情况下,允许它是没有意义的。稍后我可能会说更多…@B看§8.5,我认为原因是大括号省略只允许用于聚合类型。@B错了,它不是聚合。它有构造函数和所有的东西。@B我认为问题是关于
std::map
,但
pair
map
都不是聚合(它们都有用户提供的构造函数)。@Bаћ:在标准引用中给出的示例中,必须是聚合的
T
std::map
当然不是聚合-它有一个允许使用
{}的初始值设定项列表构造函数
首先是施工。
std::pair<int,int> p0{ 1,2 }; // single pair
std::map<int, int> m { { 1,2 } }; // map with one element
std::map<int, int> m { { 1,2 }, { 3,4} }; // map with two elements
T x = { a };