web-dev-qa-db-ja.com

コンパイラが「char」を「int」に一致させるが「short」には一致させないのはなぜですか?

私は小さなプログラムを持っています:

_#include<iostream>
using namespace std;

void f(int)   { cout << "int\n";   }
void f(short) { cout << "short\n"; }

int main(void){
    char c = 0;
    f(c);
    return 0;
}
_

intを出力します。これが「整数プロモーション」のためである場合、なぜshortが優先されないのかと感じました。

また、整数昇格が式(A = Bなど)で発生することも知っています。しかし、f(),の呼び出しには式がありませんか?

これがオーバーロード解決ルールに関連している場合、なぜcharをfに渡すと、コンパイラはintよりshortを優先するのでしょうか?

f(int)を削除すると、f(c)f(short)を呼び出します!

要約すると、私の質問は、それが「整数プロモーション」または単に「オーバーロード解決ルール」に関連するのかということです。なぜ?

69
Hind Forsum

(統合) オーバーロード解決 により、他の(統合)コンバージョンよりもプロモーションが優先されます

暗黙の変換シーケンスのランク付け

1)完全一致:変換不要、左辺値から右辺値への変換、修飾変換、関数ポインター変換、(C++ 17以降)クラス型の同じクラスへのユーザー定義変換

2)プロモーション:整数プロモーション、浮動小数点プロモーション

3)変換:整数変換、浮動小数点変換、浮動整数変換、ポインター変換、ポインターからメンバーへの変換、ブール変換、ユーザー-派生クラスからそのベースへの定義された変換

したがって、charからintへの変換は、charからshortへの変換よりも優先されます。


プロモーションとは何ですか?尋ねることができます。これは、標準で記述されている特別な種類の変換です。

なぜcharからshortがプロモーションではないのですか?、続行できます。 インテグラルプロモーション は、常にint以上のタイプになります。 shortへのプロモーションはありません。

次の暗黙的な変換は、統合プロモーションとして分類されます。

  • signed charまたはsigned shortはintに変換できます。

  • unsigned charまたはunsigned shortは、値の範囲全体を保持できる場合はintに変換でき、そうでない場合はunsigned intに変換できます。

  • charは、基になる型に応じてintまたはunsigned intに変換できます。signedcharまたはunsigned char(上記を参照)。

  • wchar_t、char16_t、およびchar32_tは、値範囲全体を保持できる次のリストから最初の型に変換できます。int、unsigned int、long、unsigned long、long long、unsigned long long。基になる型が固定されていないスコープなし列挙型は、値の範囲全体を保持できる次のリストから最初の型に変換できます:int、unsigned int、long、unsigned long、long long、またはunsigned long long値の範囲が大きい場合、積分プロモーションは適用されません。

  • 基になる型が固定されているスコープ外の列挙型は、昇格した基になる型に変換できます。

    (C++ 11以降)

  • ビットフィールド型は、ビットフィールドの値の範囲全体を表すことができる場合はintに変換でき、そうでない場合はビットフィールドの値の範囲全体を表すことができる場合は符号なしintに変換できます。型boolはintに変換できます。値falseは「0」になり、trueは1になります。


標準参照(現在の標準ドラフト):

[over.ics.scs]§

[conv.prom]§1

65
eerorika

暗黙の変換 (cppreference)から:

次の暗黙的な変換は、統合プロモーションとして分類されます。

  • [...]
  • charは、基になる型に応じてintまたは_unsigned int_に変換できます。_signed char_または_unsigned char_(上記を参照);
  • [...]

したがって、関数f(int)およびf(short)がある場合、コンパイラーは 整数プロモーション 最初に、それが可能でない場合、それはにフォールバックします 整数変換

charからintは 整数プロモーション (上記を参照)、コンパイラがそれを選択します。

f(int)がない場合、コンパイラは整数の昇格が可能な関数を見つけられず、整数変換にフォールバックします。 f(short)を検出し、charshortに変換できるため、それを選択します。

22
Rakete1111