代码之家  ›  专栏  ›  技术社区  ›  Fantastic Mr Fox

无符号短消息直接初始化的标准行为

  •  16
  • Fantastic Mr Fox  · 技术社区  · 8 年前

    今天我注意到在示例代码中:

    void print(unsigned short a) {
       std::cout << a << std::endl;
    }
    

    初始化和使用的工作方式如下:

    print(short (5));
    

    但不是这样的:

    print(unsigned short(6));
    

    打印(无符号短(6));

    这与类型无关,因为这也适用:

    typedef unsigned short ushort;
    print(ushort (6));
    

    Live example.

    所以我去搜索标准中关于值初始化的内容。结果什么都没有:

    值初始化的效果是:

    2) 如果T是非联合类类型。。。

    2) 如果T是类类型。。。

    (四) 否则 ,对象初始化为零。

    Original source .

    关于值初始化的规则是什么 POD unsigned 限定类型不能初始化值?这是因为他们 rvalues

    2 回复  |  直到 8 年前
        1
  •  21
  •   songyuanyao    7 年前

    是什么原因 unsigned

    只是因为只有一个单词类型名可以用于 functional cast expression ,而 unsigned short 不是一个单词类型名称; short

    函数强制转换表达式由一个简单类型说明符或一个typedef说明符组成(换句话说,一个单词类型名: unsigned int(expression) int*(expression) 无效),后跟括号中的单个表达式。

    正如你所展示的,你可以使用 typedef (unsigned short)(6) ,或 (unsigned short)6 .

    §7.6.1.3/1 Explicit type conversion (functional notation) [expr.type.conv] :

    一个 simple-type-specifier typename-specifier 后跟带圆括号的可选表达式列表或带大括号的init列表(初始值设定项)构造给定初始值设定项的指定类型的值。

    简单类型说明符 :

    simple-type-specifier:
      nested-name-specifier opt
     type-name
      nested-name-specifier template simple-template-id
      nested-name-specifier opt
     template-name
      char
      char16_t
      char32_t
      wchar_t
      bool
      short
      int
      long
      signed
      unsigned
      float
      double
      void
      auto
      decltype-specifier
    type-name:
      class-name
      enum-name
      typedef-name
      simple-template-id
    decltype-specifier:
      decltype ( expression )
      decltype ( auto )
    

    typename-specifier

    typename-specifier:
      typename nested-name-specifier identifier
      typename nested-name-specifier template opt
     simple-template-id
    
        2
  •  7
  •   Dietmar Kühl    8 年前

    这只是语法上的一个小问题:创建临时对象时,这两个字类型的名称不起作用。也就是说,这些都不管用

    template <typename T> void use(T);
    int main() {
        use(unsigned int());
        use(const int());
        use(long long());
    }
    

    解决方法是使用相应类型的别名,即所有这些都可以:

    template <typename T> void use(T);
    int main() {
         { using type = unsigned int; use(type()); }
         { using type = const int; use(type()); }
         { using type = long long; use(type()); }
     }
    

    template <typename T> void use(T);
    int main() {
         use((unsigned int){});
         use((const int){});
         use((long long){});
    }