Ubuntu16.04 ARM 编译 编译器版本和unordered_map map问题
源文件内使用unordered_map时候,例如如下demo
#include <unordered_map>
void foo(const std::unordered_map<int,int> &) {}
int main()
{
foo({});
}
GCC版本大于或者等于4.9,会报如下错误
map2.cpp:7:19: error: converting to ‘const std::unordered_map<int, int>’ from initializer list would use explicit constructor ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type, const hasher&, const key_equal&, const allocator_type&) [with _Key = int; _Tp = int; _Hash = std::hash<int>; _Pred = std::equal_to<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type = long unsigned int; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hasher = std::hash<int>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_equal = std::equal_to<int>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::allocator_type = std::allocator<std::pair<const int, int> >]’
其实就是 Implicit conversion failure from initializer list
如下测试来自 :https://stackoverflow.com/questions/26947704/implicit-conversion-failure-from-initializer-list
Testing with other compiler/library implementations: GCC < 4.9 accepts this without complaining,
Clang 3.5 with libstdc++ fails with a similar message,
Clang 3.5 with libc++ accepts this,
ICC 15.something accepts this (not sure which standard library it is using).
A couple of more baffling points: replacing std::unordered_map with std::map makes the error go away,
replacing foo({}) with foo foo({{}}) also makes the error go away.
Also, replacing {} with a non-empty initializer list works as expected in all cases.
实际编译过程中,我将unordered_map替换成了map,不影响适应也不会报错
来自stackover的答案解析
The indirect initialization syntax with a braced-init-list your code is using is called copy-list-initialization.
The overload resolution procedure selecting the best viable constructor for that case is described in the following section of the C++ Standard:
§ 13.3.1.7 Initialization by list-initialization [over.match.list]
When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor in two phases:
— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument.
— If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the
argument list consists of the elements of the initializer list.
If the initializer list has no elements and T has a default constructor, the first phase is omitted. In copy-list-initialization, if an explicit constructor is chosen, the
initialization is ill-formed. [ Note: This differs from other situations (13.3.1.3, 13.3.1.4), where only converting constructors are considered for copy-initialization.
This restriction only applies if this initialization is part of the final result of overload resolution. — end note ].
According to that, an initializer-list-constructor (the one callable with a single argument matching the constructor's parameter of type std::initializer_list<T>) is usually preferred to other constructors, but not if a default-constructor is available, and the braced-init-list used for list-initialization is empty.
What is important here, the set of constructors of the standard library's containers has changed between C++11 and C++14 due to LWG issue 2193. In case of std::unordered_map, for the sake of our analysis, we are interested in the following difference:
C++11:
explicit unordered_map(size_type n = /* impl-defined */,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& alloc = allocator_type()); unordered_map(initializer_list<value_type> il,
size_type n = /* impl-defined */,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& alloc = allocator_type());
C++14:
unordered_map(); explicit unordered_map(size_type n,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& alloc = allocator_type()); unordered_map(initializer_list<value_type> il,
size_type n = /* impl-defined */,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& alloc = allocator_type());
In other words, there is a different default constructor (the one that can be called without arguments) depending on the language standard (C++11/C++14), and, what is crucial, the default constructor in C++14 is now made non-explicit.
That change was introduced so that one can say:
std::unordered_map<int,int> m = {};
or:
std::unordered_map<int,int> foo()
{
return {};
}
which are both semantically equivalent to your code (passing {} as the argument of a function call to initialize std::unordered_map<int,int>).
That is, in case of a C++11-conforming library, the error is expected, as the selected (default) constructor is explicit, therefore the code is ill-formed:
explicit unordered_map(size_type n = /* impl-defined */,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& alloc = allocator_type());
In case of a C++14-conforming library, the error is not expected, as the selected (default) constructor is not explicit, and the code is well-formed:
unordered_map();
As such, the different behavior you encounter is solely related to the version of libstdc++ and libc++ you are using with different compilers/compiler options.
Replacing std::unordered_map with std::map makes the error go away. Why?
I suspect it's just because std::map in the libstdc++ version you are using was already updated for C++14.
Replacing foo({}) with foo({{}}) also makes the error go away. Why?
Because now this is copy-list-initialization {{}} with a non-empty braced-init-list (that is, it has one element inside, initialized with an empty braced-init-list {}), so the rule from the first phase of § 13.3.1.7 [over.match.list]/p1 (quoted before) that prefers an initializer-list-constructor to other ones is applied. That constructor is not explicit, hence the call is well-formed.
Replacing {} with a non-empty initializer list works as expected in all cases. Why?
Same as above, the overload resolution ends up with the first phase of § 13.3.1.7 [over.match.list]/p1.
Ubuntu16.04 ARM 编译 编译器版本和unordered_map map问题的更多相关文章
- Ubuntu16.04下编译安装OpenCV3.4.0(C++ & python)
Ubuntu16.04下编译安装OpenCV3.4.0(C++ & python) 前提是已经安装了python2,python3 1)安装各种依赖库 sudo apt-get update ...
- 在ubuntu16.04上编译android源码【转】
本文转载自:http://blog.csdn.net/fuchaosz/article/details/51487585 1 前言 经过3天奋战,终于在Ubuntu 16.04上把Android 6. ...
- Ubuntu16.04系统中不同版本Python之间的转换
Ubuntu系统自带的版本是2.7.12 安装好python3.6之后,改变一下Python的优先级(需要root权限). 在使用下面这个命令查看电脑里面有几个Python版本 update-alte ...
- Ubuntu16.04下编译OpenCV2.4.13静态库(.a文件)
Ubuntu16.04下编译OpenCV2.4.13静态库(.a文件) https://blog.csdn.net/woainishifu/article/details/79712110 我们在做项 ...
- Ubuntu16.04下安装多版本cuda和cudnn
Ubuntu16.04下安装多版本cuda和cudnn 原文 https://blog.csdn.net/tunhuzhuang1836/article/details/79545625 前言 因为之 ...
- ubuntu16.04下编译ceres-solver
一.编译环境 ubuntu16.04 二.准备工作之安装必要的库 2.1安装cmake sudo apt-get install cmake 2.2 安装google-glog + gflags su ...
- ubuntu16.04下编译安装vim8.1
之前写过一篇centos7下编译安装vim8.0的教程,ubuntu16.04相比centos7下安装过程不同在于依赖包名字的不同,其余都是一样.下面给出ubuntu16.04编译安装vim8.0需要 ...
- Ubuntu16.04下编译安装及运行单目ORBSLAM2
官网有源代码和配置教程,地址是 https://github.com/raulmur/ORB_SLAM2 1 安装必要工具 首先,有两个工具是需要提前安装的.即cmake和Git. sudo apt- ...
- ubuntu16.04安装Ros(kinetic版本)【亲测好用】
准备 1.ubuntu16.04 64位桌面版 ps:关于系统的下载和安装这里不做介绍,请自行百度,不是介绍重点 2.更改源 图上的几个勾默认是选上的,如果没有选上,选成上图这样(如果修改过勾,点击关 ...
随机推荐
- 高级C/C++编译技术之读书笔记(二)之库的概念
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- Microsoft Office 2013 (64位) 免费完整版(安装 + 激活)
Microsoft Office 2013(Office 15)是微软的新一代Office办公软件,全面采用Metro界面.Microsoft Office 2013官方下载(Office2013专业 ...
- .NET面试题总结
1.c#垃圾回收机制 从以下方面入手展开: 1.压缩合并算法 2.代的机制 3.GC调用终结器 2.委托和事件 先说它的定义:委托的本质是类,类型安全的指针,然后从用途上考虑,事件是包装的委托 ...
- L3-008 喊山 (30 分)
喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的.原来它是彝族先民用 ...
- 解决get方法传递URL参数中文乱码问题
[转]解决get方法传递URL参数中文乱码问题 来自:http://www.javaeye.com/topic/483158 应用一:解决tomcat下中文乱码问题(先来个简单的) 在tomcat下, ...
- LG3195 [HNOI2008]玩具装箱TOY
题意 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为\(1\cdots N\) ...
- 3145 code[VS]汉诺塔游戏--递归
3145 汉诺塔游戏 题目描述 Description 汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题.在A,B,C三根柱子上,有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我 ...
- mysql存入GBK编码字段信息
set @moneyStr=BASE64_ENCODE(CONVERT(CONCAT('线上报名且已交费',money,'元') using GBK));
- linux启动自动挂载分区和/etc/fstab简单修复
让后加的分区能够启动时自动挂载,需要把配置写入文件 /etc/fstab vi /etc/fstab UUID=3f5859e0-592f-42cd-b533-570422fb85be / ext ...
- MongoDB Data Model 浅谈
MongoDB 对于数据的 schema 要求很灵活. 与 MySQL 相比,collection 并不会强制文档的结构.(MySQL 在定义表时, 需要指定有哪些字段.类型.展示长度等) 因此,插入 ...