15

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

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

初始化和使用是这样的:

print(short (5));

但不是这样:

print(unsigned short(6));

main.cpp:16:8:错误:“无符号”打印之前的预期主表达式(无符号短(6));

这与类型无关,因为这也有效:

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

活生生的例子。

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

值初始化的效果是:

1)如果 T 是一个类类型......

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

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

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

4)否则,对象被零初始化。

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

POD类型的值初始化有哪些规则?unsigned限定类型无法进行值初始化的原因是什么?这是否与他们的事实有关rvalues

4

2 回答 2

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]

一个简单类型说明符或类型名称说明后跟一个带括号的可选表达式列表或一个花括号初始化列表(初始化器)构造一个给定初始化器的指定类型的值。

简单类型说明符

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 nested-name-specifier identifier
  typename nested-name-specifier template opt
 simple-template-id
于 2018-08-17T11:04:04.970 回答
7

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

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){});
}
于 2018-08-17T11:09:51.823 回答