我今天注意到在示例代码中:
void print(unsigned short a) {
std::cout << a << std::endl;
}
初始化和使用的工作方式如下:
print(short (5));
但不是这样的:
print(unsigned short(6));
主.cpp:16:8:错误:"无符号"之前的预期主表达式 打印(无符号短(6((;
这与类型无关,因为这也可以工作:
typedef unsigned short ushort;
print(ushort (6));
活生生的例子。
所以我去寻找标准对值初始化的规定。结果什么都没有:
值初始化的效果包括:
1(如果T是类类型...
2(如果T是非联合类类型...
2(如果T是类类型...
3( 如果 T 是数组类型,则 ..
4(否则,对象初始化为零。
为提高可读性而进行的修改。原始来源。
关于 POD 类型的值初始化的规则是什么?unsigned
限定类型无法进行值初始化的原因是什么?这是否与他们rvalues
的事实有关?
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
这只是语法上的一个小故障:创建临时对象时,这两个单词类型名称不起作用。也就是说,这些都不起作用
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){});
}