我最近得到了这个代码:
[0-9]\b return 'DIGIT'
[0-9]+("."[0-9]+)?\b return 'NUMBER'
不是使用10的大小初始化,而是使用一个元素std::size_t s = 10;
std::vector<int> v{s};
初始化大小为1。但是,向量具有一个带10
的显式构造函数。随着所有关于“到处都使用括号”的炒作,我预计会有很多人陷入这个陷阱。如果编译器只是警告我们试图将std::size_t
转换为size_t
,则可以避免这种情况。
为什么编译器不需要这样做?
编辑:我的原始代码有int
。显然,除非我删除const,否则我使用的编译器都不会发出警告。这是一个错误吗?
答案 0 :(得分:2)
不,这不是一个错误。参见N3337的[dcl.init.list] / 7:
缩小转化是隐式转化
...
- 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除了 其中source是常量表达式,后面是实际值 转换将适合目标类型并将生成原始 转换回原始类型时的值。
因此,只要s
为const
,代码就有效。
答案 1 :(得分:1)
而不是使用10的大小进行初始化,而不是使用一个元素
10
初始化大小为1 {/ 1}
第一个初始化列表是gready:
§13.3.1.7[over.match.list] / p1:
当非聚合类类型
T
的对象被列表初始化时 (8.5.4),重载决策分两个阶段选择构造函数:
- 最初,候选函数是类
T
的初始化列表构造函数(8.5.4),参数列表包含 初始化列表作为单个参数。- 如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中候选函数都是 类
T
的构造函数和参数列表包含 初始化列表的元素。如果初始化列表没有元素,
T
有默认值 构造函数,第一阶段被省略。在复制列表初始化中, 如果选择explicit
构造函数,则初始化为 不良形成。
因此编译器将首先尝试使用
创建向量vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
由pointed out user5389903为http://crunchify.com/how-to-fix-java-lang-unsatisfiedlinkerror-no-snappyjava-in-java-library-path-error/,因为您有一个const std::size_t s
且其值在int
的范围内,它可以将{s}
转换为std::initializer_list<int>
1}}。现在,因为我们有一个有效的std::initializer_list
,所以std::initializer_list
构造函数将被调用。