声明变量有两种类型:“ int char”


81

我是C ++初学者,正在阅读Bjarne Stroustrup的《编程:使用C ++的原理和实践》

在关于3.9.2不安全转换的部分中,作者提到了

当初始值设定项是整数文字时,编译器可以检查实际值并接受不暗示变窄的值:

int char b1 {1000};     // error: narrowing (assuming 8-bit chars)

我为这个宣言感到困惑。它使用两种类型(intchar)。我以前从未在Java和Swift中看到过这样的声明(我相对熟悉的两种语言)。这是拼写错误还是有效的C ++语法?


2
您有这本书的哪个版本和印刷版本?您是否在寻找这本书的勘误表?
一些程序员花花公子

2
那么您正在阅读什么版本?我确定Bjarne想知道这个错误。
StoryTeller-Unslander Monica '18

1
3.9.2不安全的转换“不安全的转换”是指可以将一个值隐式转换为不等于原始值的另一种类型的值。例如:int i = 20000; 字符c = i; 这种转换称为“缩小”转换。将int转换为int,char或bool将int转换为char或bool将char转换为bool
Marichyasana

15
float char是另一种有用的类型,尤其是在游泳池中。有些配有啤酒架。
Yakk-Adam Nevraumont

1
这是拼写错误还是有效的C ++语法? 尝试一下(确定,确定,否,它无效)。
保罗·桑德斯

Answers:


95

这是本书中的错误。即使没有所谓的缩小转换,这也不是有效的C ++声明。

但是,在Bjarne Stroustrup页面(第四版及更早版本)的任何勘误中都没有提到它,这很奇怪。这是一个足够明显的错误。我想,由于//error很少有人对此进行评论,所以注意到声明本身存在错误。


书中预期的代码示例可能是什么?
Pedro A

8
@Hamsterrific char b1 {1000};(因为这会引起注释中提到的错误)。我想那天Bjarne的打字手指很累。
保罗·桑德斯

1
@PaulSanders累了吗?他在int那里打了一个额外的!:-)
Leo Heinsaar,

1
@ LeoHeinsaar大声笑。好吧,那就是咖啡太多了:)也许他口吃了:)
保罗·桑德斯

是的,手指很累。它看起来像之前示例中的剪切粘贴错误。在该先前示例中,他给出了两行:int {1000};// OK [\ n] char b {a} //错误:int-> char可能会缩小[\ n],而他似乎已经将下一个示例剪切粘贴了该示例,但错过了删除“ int”部分的操作:int char b1 {1000}; //错误:缩小范围(假设为8位字符)[\ n] char b2 {48}; // OK [\ n]
L. Scott Johnson

24

这本书是错的。

令牌序列int char b1{1000};在语义上不是有效的C ++。

您试图b1使用不止一种类型进行声明,这没有任何意义。


10

这是错误的。在C / C ++中,可以通过使用并集来实现多类型声明。例如:

union {
    int i;
    char c;
} var;

var.i = 42;
/* OR */
var.c = ‘c’;

存储是相同的,因此.c和.i只是每个类型的句柄具有相同的值。


6

这在C / C ++语法中是错误的。除了unions(请参阅@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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.