直接初始化unsigned short的标准行为

Fan*_*Fox 16 c++ syntax casting initialization language-lawyer

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

void print(unsigned short a) {
   std::cout << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

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

print(short (5));
Run Code Online (Sandbox Code Playgroud)

但不是这样的:

print(unsigned short(6));
Run Code Online (Sandbox Code Playgroud)

main.cpp:16:8:错误:在'unsigned'打印之前预期的primary-expression(unsigned short(6));

并且它与该类型无关,因为这也有效:

typedef unsigned short ushort;
print(ushort (6));
Run Code Online (Sandbox Code Playgroud)

实例.

所以我去搜索标准关于值初始化的内容.事实证明:

值初始化的效果是:

1)如果T是类型...

2)如果T是非联盟类型......

2)如果T是类型...

3)如果T是数组类型,..

4)否则,对象是零初始化的.

为便于阅读而进行的修改. 原始来源.

有关POD类型值初始化的规则是什么?unsigned合格类型无法初始化的原因是什么?这更多地与他们的事实有关rvalues吗?

son*_*yao 21

unsigned合格类型无法初始化的原因是什么?

这只是因为在功能演员表达中只能使用单字类型名称,而unsigned short不是单字类型名称; short是.

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

如您所示,您可以将其typedef用作变通方法,或添加括号以将其更改为c样式的强制转换表达式,例如(unsigned short)(6),或(unsigned short)6.

从标准,§7.6.1.3/ 1显式类型转换(功能表示法)[expr.type.conv]:

简单型说明符类型名称说明符后跟带括号的可选表达式列表或通过支撑-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 )
Run Code Online (Sandbox Code Playgroud)

typename-specifier:

typename-specifier:
  typename nested-name-specifier identifier
  typename nested-name-specifier template opt
 simple-template-id
Run Code Online (Sandbox Code Playgroud)

  • @FantasticMrFox` unsigned int i(6)`是[直接初始化](https://en.cppreference.com/w/cpp/language/direct_initialization).`i`初始化为`6`. (2认同)

Die*_*ühl 7

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

template <typename T> void use(T);
int main() {
    use(unsigned int());
    use(const int());
    use(long long());
}
Run Code Online (Sandbox Code Playgroud)

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

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()); }
 }
Run Code Online (Sandbox Code Playgroud)

括号也可用于值初始化,但需要使用curlies:

template <typename T> void use(T);
int main() {
     use((unsigned int){});
     use((const int){});
     use((long long){});
}
Run Code Online (Sandbox Code Playgroud)