为什么编译器不警告unsigned to signed conversion?

时间:2015-09-29 17:26:29

标签: c++ c++11 const compiler-warnings

我最近得到了这个代码:

[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,否则我使用的编译器都不会发出警告。这是一个错误吗?

2 个答案:

答案 0 :(得分:2)

不,这不是一个错误。参见N3337的[dcl.init.list] / 7:

  

缩小转化是隐式转化

     

...

     
      
  • 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除了   其中source是常量表达式,后面是实际值   转换将适合目标类型并将生成原始   转换回原始类型时的值。
  •   

因此,只要sconst,代码就有效。

答案 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 user5389903http://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构造函数将被调用。