Pertanyaan Mendeklarasikan variabel dengan dua tipe: “int char”


Saya seorang pemula C ++, dan saya sedang membaca Pemrograman Bjarne Stroustrup: Prinsip dan Praktik Menggunakan C ++.

Di bagian tentang 3.9.2 Konversi tidak aman, penulisnya disebutkan

Ketika penginisialisasi adalah literal integer, kompiler dapat memeriksa nilai aktual dan menerima nilai yang tidak menyiratkan menyempit:

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

Saya bingung dengan pernyataan ini. Ini menggunakan dua jenis (int dan char). Saya belum pernah melihat deklarasi seperti itu di Jawa dan Swift sebelumnya (dua bahasa yang saya kenal). Apakah ini salah ketik atau sintaks C ++ yang valid?


75
2017-07-09 06:53


asal


Jawaban:


Itu kesalahan dalam buku. Itu bukan pernyataan C ++ yang valid, bahkan tanpa penyempitan konversi yang seharusnya.

Tidak disebutkan dalam salah satu dari erratas Halaman Bjarne Stroustrup(Pencetakan ke-4 dan sebelumnya), yang aneh. Ini adalah kesalahan yang cukup jelas. Saya membayangkan karena itu berkomentar //error beberapa orang melihat kesalahan dalam deklarasi itu sendiri.


91
2017-07-09 06:56



Buku itu salah.

Urutan token int char b1{1000}; bukan C ++ semantik yang valid.

Anda mencoba untuk menyatakan b1 dengan lebih dari satu jenis, yang tidak masuk akal.


22
2017-07-09 06:55



Ini salah. Di C / C ++ deklarasi multi-tipe dapat dicapai melalui penggunaan serikat pekerja. Misalnya:

union {
    int i;
    char c;
} var;

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

Penyimpanannya sama, jadi .c dan .i hanya menangani per-jenis ke nilai yang sama.


10
2017-07-10 06:41



Ini salah dalam sintaks C / C ++. Dalam kecanduan unions (lihat jawaban @Alex), ada C ++ cara untuk menyimpan hanya satu dari jenis yang disebut aviable std::variant (serikat tipe-aman):

#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
2017-07-13 08:24