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++ 语法?

4

4 回答 4

95

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

然而,在Bjarne Stroustrup 页面(第 4 版及更早版本)的任何勘误表中都没有提到它,这很奇怪。这是一个足够明显的错误。我想,因为它的评论//error很少有人注意到声明本身的错误。

于 2018-07-09T06:56:01.967 回答
24

书错了。

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

您试图b1用一种以上的类型声明,这是没有意义的。

于 2018-07-09T06:55:57.767 回答
10

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

union {
    int i;
    char c;
} var;

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

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

于 2018-07-10T06:41:22.427 回答
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
}
于 2018-07-13T08:24:53.273 回答