我是C ++初学者,我正在阅读 Bjarne Stroustrup的《编程:使用C ++的原理和实践》 。
在 3.9.2不安全转换一节中,作者提到了
当初始化程序是整数文字时,编译器可以检查实际值并接受不表示变窄的值:
int char b1 {1000}; // error: narrowing (assuming 8-bit chars)
我对这个声明感到困惑。它使用两种类型(int
和char
)。我以前从未在Java和Swift中看到过这样的声明(我相对熟悉的两种语言)。这是错字还是有效的C ++语法?
答案 0 :(得分:94)
这是书中的错误。即使没有所谓的缩小转换,这也不是有效的C ++声明。
尽管如此,Bjarne Stroustrup's page(第四版及更早版本)的任何勘误中均未提及。这是一个足够明显的错误。我想,既然用//error
进行了注释,很少有人注意到声明本身的错误。
答案 1 :(得分:23)
这本书是错误的。
令牌序列int char b1{1000};
在语义上不是有效的C ++。
您正在尝试使用多种类型声明b1
,这是没有道理的。
答案 2 :(得分:10)
这是错误的。 在C / C ++中,可以通过使用并集来实现多类型声明。例如:
union {
int i;
char c;
} var;
var.i = 42;
/* OR */
var.c = ‘c’;
存储空间是相同的,因此.c和.i只是每个类型的句柄具有相同的值。
答案 3 :(得分:6)
这在C / C ++语法中是错误的。除了union
(请参阅@Alex答案)之外,还有一种C ++方法仅存储一种称为std::variant
(类型安全的并集)的可用类型:
#include <variant>
#include <string>
int main()
{
std::variant<int, float> v, w;
v = 12; // v contains int
int i = std::get<int>(v);
w = std::get<int>(v);
w = std::get<0>(v); // same effect as the previous line
w = v; // same effect as the previous line
// std::get<double>(v); // error: no double in [int, float]
// std::get<3>(v); // error: valid index values are 0 and 1
try {
std::get<float>(w); // w contains int, not float: will throw
}
catch (std::bad_variant_access&) {}
std::variant<std::string> v("abc"); // converting constructors work when unambiguous
v = "def"; // converting assignment also works when unambiguous
}