Объявление переменной с двумя типами: "int char"
Я новичок C++, и я читаю Bjarne Stroustrup Программирование: принципы и практика с использованием C++.
В разделе, посвященном 3.9.2 Небезопасные преобразования, автор упомянул
Когда инициализатор является целым литералом, компилятор может проверить фактическое значение и принять значения, которые не подразумевают сужение:
int char b1 {1000}; // error: narrowing (assuming 8-bit chars)
Я озадачен этой декларацией. Он использует два типа (int
и char
). Я никогда не видел такого объявления в Java и Swift раньше (два языка, с которыми я довольно хорошо знаком). Является ли это опечаткой или действительным синтаксисом C++?
Ответы
Ответ 1
Это ошибка в книге. Это не является допустимым C++ декларацией, даже без предполагаемого сужения преобразования.
Он не упоминается ни в одной из ошибок на странице Bjarne Stroustrup (4-я печать и ранее), хотя это странно. Это достаточно явная ошибка. Я предполагаю, что, поскольку он прокомментировал //error
некоторые люди замечают ошибку в самой декларации.
Ответ 2
Книга неверна.
Последовательность токенов int char b1{1000};
не является семантически допустимым C++.
Вы пытаетесь объявить b1
более чем одним типом, что не имеет смысла.
Ответ 3
Это неверно. В C/C++ многотипные декларации могут быть достигнуты с помощью профсоюзов. Например:
union {
int i;
char c;
} var;
var.i = 42;
/* OR */
var.c = ‘c;
Хранилище такое же, поэтому.c и.i - это только дескрипторы одного типа для одного и того же значения.
Ответ 4
Это неверно в синтаксисе 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
}