直接初始化无符号short的标准行为

时间:2018-08-17 10:58:11

标签: c++ syntax casting initialization language-lawyer

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

img {
  margin-bottom: -120px;
  z-index: 1;
  position: relative;
}

.text {
  border: solid 1px red;
  min-height: 200px;
  z-index: 2;
  background-color: pink;
  position: relative;
  width: 100%;
  margin-top: 20px;
}

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

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet" />
<nav class="navbar navbar-dark bg-dark">
  <a class="navbar-brand" href="#"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSqrfVof7CYYRtsdCu1VD4AWoPB2gs25PP5hQAuhOwhZngrOhsS" alt="brand"> </a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample01" aria-controls="navbarsExample01" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExample01">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="https://example.com" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
        <div class="dropdown-menu" aria-labelledby="dropdown01">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
    </ul>
    <form class="form-inline my-2 my-md-0">
      <input class="form-control" type="text" placeholder="Search" aria-label="Search">
    </form>
  </div>
</nav>

<div class="text">


</div>

但不是这样:

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

main.cpp:16:8:错误:“未签名”之前的预期主表达式     print(unsigned short(6));

与类型无关,因为它也可以工作:

print(short (5));

Live example.

因此,我去搜索标准关于值初始化的内容。没结果:

  

值初始化的影响是:

     

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

     

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

     

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

     

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

     

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

为便于阅读而进行的修改。 Original source

关于POD类型的值初始化的规则是什么?无法对print(unsigned short(6)); 个限定类型进行值初始化的原因是什么?这与他们是typedef unsigned short ushort; print(ushort (6)); 的事实有关吗?

2 个答案:

答案 0 :(得分:21)

  

无法对unsigned个限定类型进行值初始化的原因是什么?

这仅仅是因为functional cast expression中只能使用单字类型名称,而unsigned short不是单字类型名称; short是。

  

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

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

根据标准§7.6.1.3/1 Explicit type conversion (functional notation) [expr.type.conv]

  

一个simple-type-specifiertypename-specifier,后跟一个带括号的可选表达式列表或一个括号初始列表(初始化程序),以给定初始化程序的方式构造指定类型的值。

还有simple-type-specifier

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

答案 1 :(得分: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()); }
 }

尽管需要使用curly,但也可以将括号用于值初始化:

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