受到this answer的启发,我尝试了下一个例子:
#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;
}
}
并且编译失败并出现下一条错误消息(g ++ 4.6.1):
gh.cpp:11:5: error: could not convert '{1, "ONE", 2, "TWO"}' from '<brace-enclosed initializer list>' to 'const std::map<int, std::basic_string<char> >'
我知道如何解决它:
const std::map< int, std::string > mapping = {
{1, "ONE"},
{2, "TWO"},
};
但为什么编译在顶部示例中失败?
答案 0 :(得分:24)
因为地图是非聚合的,并且包含非聚合元素(std::pair<key_type, mapped_type>
),所以它需要一个初始化列表,其中包含每个对的初始化列表。
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
请记住,大括号的规则适用于聚合,因此它们不适用于此。
答案 1 :(得分:9)
C ++ 11标准只允许在目标是聚合时省略大括号:
8.5.1聚合[dcl.init.aggr]
聚合是一个没有用户提供的数组或类(第9条) 构造函数(12.1),非静态的支撑或相等初始化器 数据成员(9.2),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)。
...
(第11段)
在表格
的声明中T x = { a };
大括号可以在初始化列表中省略,如下所示。如果 初始化列表以左括号开头,然后是成功 逗号分隔的initializer-clauses列表初始化成员 分组;有更多的是错误的 初始化者 - 条款比成员。但是,如果是初始化列表 对于子聚合不是以左括号开始,而是仅以左括号开头 从列表中获取足够的初始化子句来初始化 分组成员;任何剩余的初始化条款都是 左边初始化聚合的下一个成员 current subaggregate是会员。
答案 2 :(得分:3)
自从我完成C ++以来已经很久了,但我的猜测是因为std::map
期待一组单独的对象,每个对象都包含一个键和一个值对。
单个列表中的单个项目没有意义,并且也很难阅读(以确保您有多个项目可以被2整除)。