用两种类型声明一个变量:"int char"

81

我是一名C++初学者,正在阅读Bjarne Stroustrup的《Programming: Principles and Practice Using C++》。

在“3.9.2 不安全的类型转换”一节中,作者提到:

当初始化器为整型字面值时,编译器可以检查实际值并接受不会导致缩小的值:

int char b1 {1000};     // error: narrowing (assuming 8-bit chars)
我对这个声明感到困惑。它使用了两种类型(intchar)。在我熟悉的 Java 和 Swift 中从未见过这样的声明。这是一个打字错误还是一个有效的 C++ 语法?

2
你有这本书的哪个版本和印刷品?你有没有查找过这本书的勘误表? - Some programmer dude
2
你读的是哪个版本?我相信Bjarne会想知道这个错误。 - StoryTeller - Unslander Monica
1
3.9.2 不安全的转换 所谓不安全的转换是指一个值可以被隐式地转换为另一种类型的值,而这种类型并不等于原始值。例如:int i = 20000; char c = i; 这样的转换被称为“缩小”转换。double 转 int、char 或 bool int 转 char 或 bool char 转 bool - Marichyasana
15
“浮动坐垫”是另一种实用的类型,尤其在游泳池中。一些还带有一个啤酒杯架。 - Yakk - Adam Nevraumont
1
这是一个打字错误还是有效的C++语法?试一下(好吧,好吧,它不是有效的)。 - Paul Sanders
显示剩余5条评论
4个回答

95
这是书中的错误。即使没有所谓的缩小转换,这也不是有效的C++声明。
Bjarne Stroustrup的页面上(第4版印刷和之前),没有提到任何勘误,这很奇怪。这是一个非常明显的错误。我想由于它被注释为//error,很少有人注意到声明本身的错误。

这本书中可能预期的代码示例是什么? - Pedro A
8
@Hamsterrific 在这里声明一个字符变量 b1 并赋值为 1000,但实际上这会引发评论中提到的错误。我猜 Bjarne 那天打字打累了。 - Paul Sanders
1
@PaulSanders 累了吗?他多打了一个 int! :-) - Leo Heinsaar
1
@LeoHeinsaar 哈哈,好的,可能是喝太多咖啡了 :) 或者他有口吃 :) - Paul Sanders
是的:手指累了。看起来这是从前面的例子中复制粘贴的错误。在那个先前的例子中,他给出了两行:int a {1000}; // OK [\n] char b {a} // error: int -> char might narrow [\n]他似乎将该示例剪切并粘贴到下一个示例中,并错过了删除“int”部分:int char b1 {1000}; // error: narrowing (assuming 8-bit chars) [\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++语法中是错误的。除了使用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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接