Оголошення змінної двома типами: “int char”


81

Я початківець на C ++, і я читаю програмування Бьярна Страуструпа: Принципи та практика використання C ++ .

У розділі про 3.9.2 небезпечні перетворення автор згадав

Коли ініціалізатором є цілочисельний літерал, компілятор може перевірити фактичне значення та прийняти значення, які не передбачають звуження:

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

Я здивований цією заявою. Він використовує два типи ( intі char). Я ніколи раніше не бачив такої заяви в Java та Swift (дві мови, якими я відносно знайомий). Це друкарська помилка чи дійсний синтаксис C ++?


2
Яке видання та друк книги у вас є? Ви шукали помилки книги?
Якийсь чувак-програміст

2
То яку версію ви читаєте? Я впевнений, що Бьярн хотів би знати про цю помилку.
StoryTeller - Unslander Monica

1
3.9.2 Небезпечні перетворення Під небезпечними перетвореннями ми маємо на увазі, що значення можна неявно перетворити на значення іншого типу, яке не дорівнює вихідному значенню. наприклад: int i = 20000; char c = i; Такі перетворення називаються перетвореннями, що звужуються. double to int, char or bool int to char або bool char to bool
Marichyasana

15
Це float charще один корисний тип, особливо в басейнах. Деякі приходять із тримачем для пива.
Якк - Адам Неврамонт

1
Це друкарська помилка чи дійсний синтаксис C ++? Спробуйте (Добре, Добре, ні, це не дійсно).
Пол Сандерс

Відповіді:


95

Це помилка в книзі. Це не є допустимою декларацією C ++, навіть без передбачуваного перетворення звуження.

Однак це не згадується в жодних помилках на сторінці Бьярна Струструпа (4-та друк і раніше), що є дивним. Це досить явна помилка. Думаю, оскільки це коментується, коли //errorмало хто помічає помилку в самій декларації.


Який, мабуть, передбачався приклад коду в книзі?
Педро А

8
@Hamsterrific char b1 {1000};(оскільки це спровокує помилку, згадану в коментарі). Я здогадуюсь, що в той день пальці, які друкувала Бьярн, втомилися.
Пол Сандерс,

1
@PaulSanders Втомився? Він набрав там зайвий int! :-)
Лев

1
@ LeoHeinsaar Lol. Добре, занадто багато кави тоді :) Або, можливо, у нього заїкається :)
Пол Сандерс

Так: пальці втомлені. Це схоже на помилку cut-n-paste із прикладу, що передував їй. У цьому попередньому прикладі він подає два рядки: int a {1000}; // Добре [\ n] char b {a} // помилка: int -> char може звузити [\ n], і він, схоже, вирізав-n-вставив цей приклад для наступного і пропустив видалення частини "int" : int char b1 {1000}; // помилка: звуження (припускаючи 8-бітові символи) [\ n] char b2 {48}; // Добре [\ n]
Л. Скотт Джонсон,

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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.