代码之家  ›  专栏  ›  技术社区  ›  Sarfaraz Nawaz

0,int()和int{}之间有什么区别?

  •  5
  • Sarfaraz Nawaz  · 技术社区  · 11 年前

    int() int{} 常数 值的表达式等于 0 ,我认为它们是等价和可互换的,因此编译器必须平等对待它们。例如

     int a[0];      //error: zero-sized array not allowed in ISO C++
     int b[int()];  //error: zero-sized array not allowed in ISO C++
     int c[int{}];  //error: zero-sized array not allowed in ISO C++
    

    但似乎有一些角落的情况下,它们是不可互换的。

    • 初始化指针时:

      int *p = 0;     //ok
      int *q = int(); //error - by clang only
      int *r = int{}; //error - by gcc and clang both
      

      看见 GCC Clang 信息。我怀疑这是两个编译器中的一个错误,因为我希望它们在这种情况下可以互换,但我很高兴被证明是错误的。:-)

    • 传递到类模板时:

      template<int N> struct X{};
      
      X<0>      x1; //ok
      X<int{}>  x2; //ok (same as X<0>)
      X<int()>  x3; //error  
      

      看见 GCC Clang 信息。

      我找到了语法 X<int()> 正如我以前看到的(可能也使用过)类似的语法一样,非常熟悉,例如 std::function<int()> ,模板参数 整数() 预计为 函数类型 (而不是 0 )不进行争论并返回 int 。但我想知道规范中关于这一点的部分 整数() 将被视为函数 类型 并且不等同于 整数{} 它总是 0 .

    1 回复  |  直到 11 年前
        1
  •  5
  •   willj    11 年前

    表达式 int() int{} 都是整数类型的常量表达式prvalue,计算结果为零,因此可以与文字互换 0 在任何需要整数类型的整数常量表达式prvalue的上下文中,该表达式的计算结果为零。

    两个表达式都满足中指定的常量表达式的要求 5.19常量表达式[expr.const] .

    关于 X<int()> ,标准规定 整数() 在此上下文中不被解释为表达式:

    14.3模板参数[temp.arg]

    在一个 模板参数 ,之间的歧义 类型id 和一个 表示 已解析为 类型id ,无论对应的形式如何 模板参数 .

    关于指针转换:

    4.10指针转换[conv.ptr]

    空指针常量是整数类型的整数常量表达式(5.19)prvalue,计算结果为零 或类型为的prvalue std::nullptr_t .

    基于上述段落 整数() 整数{} 是空指针常量表达式。这指向一个(非常小的)编译器错误,尽管有一个打开的缺陷报告( 903 )这可能导致本段发生变化:

    CWG一致认为,只有文字0才应被视为空指针常量,而不是当前指定的任何任意零值常量表达式。

    以下措辞涉及该表达的价值 整数() :

    8.5初始化程序[dcl.init]

    对T类型的对象或引用进行零初始化意味着:

    [ 不适用的省略条款 ]

    如果T是标量类型(3.9),则将对象设置为值0(零),作为积分常数表达式, 转换为T

    [...]

    对T类型的对象进行值初始化意味着:

    如果T是一个(可能是cv限定的)类类型(第9条),具有用户提供的构造函数(12.1),则 调用了T的默认构造函数(如果T没有可访问的默认值,则初始化格式不正确 构造函数);

    [ 不适用的省略条款 ]

    否则,对象被零初始化。

    初始化器是一组空括号的对象,即(),应进行值初始化。

    以及 整数{} :

    8.5.4列表初始化[dcl.init.List]

    类型为T的对象或引用的列表初始化定义如下:

    如果初始值设定项列表没有元素,并且T是具有默认构造函数的类类型,则对象为 值已初始化。

    [ 不适用的省略条款 ]

    否则,如果初始值设定项列表中没有元素,则对象被值初始化。

    所有引用自C++工作草案标准N3337。