如何在编译时自动区分长短?
How can auto distinguish short from long at compile time?
我很高兴在我的 C++ 程序中使用 auto
变量。我知道用 auto
声明的变量使用模板规则来推导变量类型,但我对它如何适用于数字类型感到困惑。假设我有:
auto foo = 12;
foo
的类型可以合理地设为 int
甚至 unsigned char
。但是假设稍后在我的程序中我做了一些数学运算并为 foo 分配了 40 亿的值。那时,我希望 foo
成为类型 unsigned int
或者 long
.
编译器如何预测稍后将在程序中分配的值?
编译器使用存在的信息,在您的情况下是整数文字 12
。所以它推断 foo
是 int
类型。它没有预料到任何事情。您可以使用适当的 integer literal 后缀:
auto foo = 12ul;
强制将 foo
推断为 unsigned long
。您不能将变量定义为 int
类型,然后期望编译器以某种方式将其更改为另一种类型,只是因为您分配了一个不适合以前使用的类型的不同值。如果你这样做,它只会导致整数溢出,这是未定义的行为。
有关该主题的更多信息,请查看 auto specifier and auto type deduction 参考资料。
At that point, I would want foo
to have type unsigned int
or perhaps long
.
这不是语言的工作方式。变量不能在运行时更改其类型。如果您将变量定义并初始化为 auto foo = 12;
,这意味着 与 int foo = 12;
完全相同 int foo = 12;
,而不管任何未来的赋值,因为 [=15] 的类型=] 是 int
.
How can compilers anticipate values that will be assigned later in the program?
他们不必。稍后分配的值将转换为变量的类型。如果该值超出该类型的范围,则具体规则取决于您处理的类型。
“foo 的类型可以是 int 甚至是 unsigned char”
不,不能。 C++ 中的每个表达式都有一个类型,并且在语言中有明确的定义。在您的情况下,表达式是整数文字,因此类型对应于文字。具体是什么类型,由rules:
定义
The type of the literal
The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used.
no suffix - int, long int, long long int(since C++11)
“编译器如何预测稍后将分配的值
程序?"
不能。类型在你声明变量的时候就确定了,以后不能改变。
The type for foo could reasonably be int or even unsigned char
它可能是很多东西,但实际上是只有一件事。
整数文字 12
的类型为 int
。
期间。
But suppose later in my program, I do some math and assign foo a value of 4 billion. At that point, I would want foo to have type unsigned int or perhaps long. How can compilers anticipate values that will be assigned later in the program?
他们不能,他们也不会。 foo
的类型不会改变。 foo
没有类型 auto
(没有这样的东西);它的类型为 int
。从此以后,您的程序就好像您编写了 int foo = 12;
一样。 deduction/automation 到此结束。
就我个人而言,我不会对这些立即常量使用 auto,但值来自另一个方法调用,或从另一个变量赋值。
如果您确实想要一种方法来定义一个变量以匹配另一个变量的类型,那么您可以 inter-operate 使用它,但您想要分配一个常量值,然后使用 decltype 来确保其大小兼容:
decltype(otherVar) myVar = 1234;
myVar += otherVar; // will work just as well as otherVar += myVar
无论如何,类型由文字常量指定,未修饰的 12 将定义一个 int。
但是,您可以用 U 装饰常量,使其无符号,或用 L 使其长,甚至用 LL 使其 super-long。不幸的是,没有强制它变短或变字符的等效项!
我的建议是,这不是使用 auto
的好地方。您知道哪些因素决定了您需要的类型,并且无法从直接上下文中推断出它们。 (但是,如果您可以将变量编写为单个静态赋值,那将永远不会发生。)
如果您知道变量需要能够保存至少 40 亿的值,请将其声明为 unsigned long
或 long long int
。或者,如果您真的想针对这些类型的宽度(例如 long
为 32 位宽以支持遗留代码的平台,但本机字大小为 64 位)的不幸选择进行防御性编码,请将其声明为uint_fast32_t
或 int_fast64_t
。或者如果你想要最小的,而不是最快的,uint_least32_t
。 (有时,最快的代码是在缓存中保留最多值的代码!)
如果您真正想要的是可以容纳 40 亿的最快的有符号或无符号类型,请说出您的意思!
像所有其他答案一样,没有魔法。
但是您可以通过其他一些方式预先指定所需的类型。
auto foo = long(12);
std::cout << typeid(foo).name() << std::endl;
auto anotherFoo = long long (12);
//Some compilers may not allow multiple words like "long long"
//In that case you can use using keyword.
using llong = long long;
auto someOtherFoo = llong (12);
我很高兴在我的 C++ 程序中使用 auto
变量。我知道用 auto
声明的变量使用模板规则来推导变量类型,但我对它如何适用于数字类型感到困惑。假设我有:
auto foo = 12;
foo
的类型可以合理地设为 int
甚至 unsigned char
。但是假设稍后在我的程序中我做了一些数学运算并为 foo 分配了 40 亿的值。那时,我希望 foo
成为类型 unsigned int
或者 long
.
编译器如何预测稍后将在程序中分配的值?
编译器使用存在的信息,在您的情况下是整数文字 12
。所以它推断 foo
是 int
类型。它没有预料到任何事情。您可以使用适当的 integer literal 后缀:
auto foo = 12ul;
强制将 foo
推断为 unsigned long
。您不能将变量定义为 int
类型,然后期望编译器以某种方式将其更改为另一种类型,只是因为您分配了一个不适合以前使用的类型的不同值。如果你这样做,它只会导致整数溢出,这是未定义的行为。
有关该主题的更多信息,请查看 auto specifier and auto type deduction 参考资料。
At that point, I would want
foo
to have typeunsigned int
or perhapslong
.
这不是语言的工作方式。变量不能在运行时更改其类型。如果您将变量定义并初始化为 auto foo = 12;
,这意味着 与 int foo = 12;
完全相同 int foo = 12;
,而不管任何未来的赋值,因为 [=15] 的类型=] 是 int
.
How can compilers anticipate values that will be assigned later in the program?
他们不必。稍后分配的值将转换为变量的类型。如果该值超出该类型的范围,则具体规则取决于您处理的类型。
“foo 的类型可以是 int 甚至是 unsigned char”
不,不能。 C++ 中的每个表达式都有一个类型,并且在语言中有明确的定义。在您的情况下,表达式是整数文字,因此类型对应于文字。具体是什么类型,由rules:
定义The type of the literal
The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used.
no suffix - int, long int, long long int(since C++11)
“编译器如何预测稍后将分配的值 程序?"
不能。类型在你声明变量的时候就确定了,以后不能改变。
The type for foo could reasonably be int or even unsigned char
它可能是很多东西,但实际上是只有一件事。
整数文字 12
的类型为 int
。
期间。
But suppose later in my program, I do some math and assign foo a value of 4 billion. At that point, I would want foo to have type unsigned int or perhaps long. How can compilers anticipate values that will be assigned later in the program?
他们不能,他们也不会。 foo
的类型不会改变。 foo
没有类型 auto
(没有这样的东西);它的类型为 int
。从此以后,您的程序就好像您编写了 int foo = 12;
一样。 deduction/automation 到此结束。
就我个人而言,我不会对这些立即常量使用 auto,但值来自另一个方法调用,或从另一个变量赋值。
如果您确实想要一种方法来定义一个变量以匹配另一个变量的类型,那么您可以 inter-operate 使用它,但您想要分配一个常量值,然后使用 decltype 来确保其大小兼容:
decltype(otherVar) myVar = 1234;
myVar += otherVar; // will work just as well as otherVar += myVar
无论如何,类型由文字常量指定,未修饰的 12 将定义一个 int。
但是,您可以用 U 装饰常量,使其无符号,或用 L 使其长,甚至用 LL 使其 super-long。不幸的是,没有强制它变短或变字符的等效项!
我的建议是,这不是使用 auto
的好地方。您知道哪些因素决定了您需要的类型,并且无法从直接上下文中推断出它们。 (但是,如果您可以将变量编写为单个静态赋值,那将永远不会发生。)
如果您知道变量需要能够保存至少 40 亿的值,请将其声明为 unsigned long
或 long long int
。或者,如果您真的想针对这些类型的宽度(例如 long
为 32 位宽以支持遗留代码的平台,但本机字大小为 64 位)的不幸选择进行防御性编码,请将其声明为uint_fast32_t
或 int_fast64_t
。或者如果你想要最小的,而不是最快的,uint_least32_t
。 (有时,最快的代码是在缓存中保留最多值的代码!)
如果您真正想要的是可以容纳 40 亿的最快的有符号或无符号类型,请说出您的意思!
像所有其他答案一样,没有魔法。
但是您可以通过其他一些方式预先指定所需的类型。
auto foo = long(12);
std::cout << typeid(foo).name() << std::endl;
auto anotherFoo = long long (12);
//Some compilers may not allow multiple words like "long long"
//In that case you can use using keyword.
using llong = long long;
auto someOtherFoo = llong (12);