web-dev-qa-db-ja.com

2つのタイプを持つ変数の宣言: "int char"

私はC++初心者で、Bjarne Stroustrupのプログラミング:C++を使用した原則と実践を読んでいます。

.9.2安全でない変換のセクションで、著者は言及しました

初期化子が整数リテラルである場合、コンパイラは実際の値を確認し、狭めることを意味しない値を受け入れることができます。

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

私はこの宣言に困惑しています。 2つのタイプ(intおよびchar)を使用します。 JavaとSwiftでこのような宣言を見たことはありません(比較的よく知っている2つの言語)。これはタイプミスか有効なC++構文ですか?

80
Thor

それは本の間違いです。それは、想定される縮小変換がなくても、有効なC++宣言ではありません。

Bjarne Stroustrupのページ (4th以前の印刷)のエラータには記載されていませんが、これは奇妙です。それは明らかな間違いです。 //errorでコメントされているので、宣言自体の間違いに気付く人はほとんどいないと思います。

94
StoryTeller

本は間違っています。

トークンシーケンスint char b1{1000};は、意味的に有効なC++ではありません。

b1を複数の型で宣言しようとしていますが、これは意味がありません。

23
Bathsheba

間違っています。 C/C++では、共用体を使用してマルチタイプ宣言を実現できます。例えば:

union {
    int i;
    char c;
} var;

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

ストレージは同じであるため、.cと.iは、同じ値に対するタイプごとのハンドルにすぎません。

10
Alex

これは、C/C++構文では間違っています。 unions(@Alexの回答を参照)に加えて、 std::variant (type-safe union)と呼ばれる使用可能な型の1つのみを格納するC++の方法があります。

#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
}
6
val