1. ホーム
  2. c++

[解決済み] なぜ最も負の数のint型は、曖昧な関数のオーバーロードに関するエラーを引き起こすのでしょうか?

2023-04-01 21:15:47

質問

C++で関数のオーバーロードについて勉強しているのですが、こんなことに遭遇しました。

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 というエラーでコンパイルに失敗します。

オーバーロードの呼び出し display(long int) はあいまいです

しかし、同じ値を int に取り込み、その値を印刷すると 2147483648 . 私はこの動作に文字通り困惑しています。

なぜ、最も負の数が渡されたときだけこの動作が見られるのでしょうか?(この動作は short が使われている場合 -32768 - と併用され、負の数と正の数が同じ2進数表現である場合には)

使用コンパイラ: g++ (GCC) 4.8.5

どのように解決するのですか?

これは非常に微妙なエラーです。 あなたが見ているものは、C++ に負の整数リテラルが存在しないことの結果です。 もし私たちが [lex.icon] を見てみると、ある 整数リテラル ,

整数値リテラル

10進リテラル 整数接尾辞 opt

        [...]

10進数-リテラル ,

decimal-literal:

非ゼロ桁

10進数リテラル <サブ opt 桁

ここで 数字 [0-9] であり ゼロ以外の数字 [1-9] で、接尾辞 par は以下のいずれかです。 u , U , l , L , ll または LL . このどこにも - を10進数リテラルの一部として含んでいません。

また、§2.13.2において、我々は

また 整数リテラル は、ピリオドや指数部を持たない一連の数字で、値を決定する際に無視されるシングルクォートで区切られることもあります。整数リテラルは,基底を指定する接頭辞と型を指定する接尾辞を持つことができる。一連の数字のうち、辞書的に最初の数字が最も重要です。 A 10進数 整数リテラル (基本 10) は 0 以外の数字で始まり、一連の 10 進数で構成されます。

(強調)

ということは --2147483648 は、単項演算子 operator - . つまり -2147483648 が実際に扱われるのは -1 * (2147483648) . そのため 2147483648 には一つ多いので int に昇格します。 long int に昇格し、それが一致しないために曖昧さが生じます。

もし、ある型の最小値や最大値をポータブルな方法で取得したい場合には

std::numeric_limits<type>::min();  // or max()