为什么最负的 int 值会导致模棱两可的函数重载错误?
我正在学习 C++ 中的函数重载并遇到了这个问题:
I'm learning about function overloading in C++ and came across this:
void display(int a)
{
cout << "int" << endl;
}
void display(unsigned a)
{
cout << "unsigned" << endl;
}
int main()
{
int i = -2147483648;
cout << i << endl; //will display -2147483648
display(-2147483648);
}
据我了解,在 int
范围内给出的任何值(在我的情况下 int
是 4 字节)都将调用 display(int)
并且超出此范围的任何值都将是模棱两可的(因为编译器无法决定调用哪个函数).它适用于完整范围的 int
值,但其最小值即 -2147483648
编译失败并出现错误
From what I understood, any value given in the int
range (in my case int
is 4 byte) will call display(int)
and any value outside this range will be ambiguous (since the compiler cannot decide which function to call). It is valid for the complete range of int
values except its min value i.e. -2147483648
where compilation fails with the error
调用重载的display(long int)
不明确
但是对 int
取相同的值并打印该值会得到 2147483648
.我真的对这种行为感到困惑.
But taking the same value to an int
and printing the value gives 2147483648
. I'm literally confused with this behavior.
为什么只有在传递最大负数时才会观察到这种行为?(如果 short
与 -32768
一起使用,行为是相同的 - 事实上,在负数和正数具有相同二进制表示的任何情况下)
Why is this behavior observed only when the most negative number is passed? (The behavior is the same if a short
is used with -32768
- in fact, in any case where the negative number and positive number have the same binary representation)
使用的编译器:g++ (GCC) 4.8.5
Compiler used: g++ (GCC) 4.8.5
推荐答案
这是一个非常微妙的错误.您所看到的是 C++ 中没有负整数文字的结果.如果我们查看 [lex.icon] 我们会得到一个 integer-literal,
This is a very subtle error. What you are seeing is a consequence of there being no negative integer literals in C++. If we look at [lex.icon] we get that a integer-literal,
整型
decimal-literal integer-suffixopt
[...]
integer-literal
decimal-literal integer-suffixopt
[...]
可以是十进制文字,
十进制文字:
非零位
decimal-literal ' opt digit
decimal-literal:
nonzero-digit
decimal-literal ’ opt digit
其中 digit 是 [0-9]
并且 nonzero-digit 是 [1-9]
并且后缀par可以是u
、U
、l
、L
、ll
或 LL
.这里没有任何地方包含 -
作为十进制文字的一部分.
where digit is [0-9]
and nonzero-digit is [1-9]
and the suffix par can be one of u
, U
, l
, L
, ll
, or LL
. Nowhere in here does it include -
as being part of the decimal literal.
在 §2.13.2 中,我们还有:
In §2.13.2, we also have:
整数文字 是一个没有句点或指数部分的数字序列,在确定其值时可以忽略单引号.整数文字可能有一个指定其基数的前缀和一个指定其类型的后缀.数字序列的词汇第一个数字是最重要的.十进制整数文字(以十为底)以非 0 的数字开头,由一系列十进制数字组成.
An integer literal is a sequence of digits that has no period or exponent part, with optional separating single quotes that are ignored when determining its value. An integer literal may have a prefix that specifies its base and a suffix that specifies its type. The lexically first digit of the sequence of digits is the most significant. A decimal integer literal (base ten) begins with a digit other than 0 and consists of a sequence of decimal digits.
(强调我的)
这意味着-2147483648
中的-
是一元操作符-
.这意味着 -2147483648
实际上被视为 -1 * (2147483648)
.由于 2147483648
对于您的 int
来说太多了,它被提升为 long int
并且歧义来自不匹配.
Which means the -
in -2147483648
is the unary operator -
. That means -2147483648
is actually treated as -1 * (2147483648)
. Since 2147483648
is one too many for your int
it is promoted to a long int
and the ambiguity comes from that not matching.
如果您想以可移植的方式获取类型的最小值或最大值,您可以使用:
If you want to get the minimum or maximum value for a type in a portable manner you can use:
std::numeric_limits<type>::min(); // or max()
相关文章