Clash Royale CLAN TAG#URR8PPP
Declaring a variable with two types: “int char”
I'm a C++ beginner, and I'm reading Bjarne Stroustrup's Programming: Principles and Practice Using C++.
In the section on 3.9.2 Unsafe conversions, the author mentioned
When the initializer is an integer literal, the compiler can check the actual value and accept values that do not imply narrowing:
int char b1 {1000}; // error: narrowing (assuming 8-bit chars)
I'm puzzled by this declaration. It uses two types (int
and char
). I have never seen such declaration in Java and Swift before (the two languages I'm relatively familiar with). Is this a typo or a valid C++ syntax?
int
char
float char
4 Answers
4
It's a mistake in the book. That is not a valid C++ declaration, even without the supposed narrowing conversion.
It isn't mentioned in any of the erratas on Bjarne Stroustrup's page(4th printing and earlier), though, which is odd. It's a clear enough mistake. I imagine since it's commented with //error
few people notice the mistake in the declaration itself.
//error
char b1 {1000};
int
The book is wrong.
The token sequence int char b1{1000};
is not semantically valid C++.
int char b1{1000};
You are trying to declare b1
with more than one type, which makes no sense.
b1
It is wrong.
In C/C++ the multi-type declarations can be achieved via the use of unions. Eg:
union {
int i;
char c;
} var;
var.i = 42;
/* OR */
var.c = ‘c’;
The storage is the same, so .c and .i are just per-type handles to the same value.
This is wrong in C/C++ syntax. In addiction to union
s (see @Alex answer), there is C++ way to store only one of aviable types called std::variant
(type-safe union):
union
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
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Which edition and printing of the book do you have? Have you looked for an errata of the book?
– Some programmer dude
Jul 9 at 6:57