だから、私はこのようなものを書いた
#include <iostream>
using namespace std;
void f(int32_t i)
{
cout << "int32: " << i << endl;
}
void f(int16_t i)
{
cout << "int16: " << i << endl;
}
void f(int8_t i)
{
cout << "int8: " << i << endl;
}
void f(uint32_t i)
{
cout << "uint32: " << i << endl;
}
void f(uint16_t i)
{
cout << "uint16: " << i << endl;
}
int main() {
uint8_t i = 0u;
f(i);
return 0;
}
そしてそれは印刷されました
int32: 0
私は少し混乱しています:
これは明確に定義された動作ですか、それとも実装固有ですか?
ここでどのオーバーロードが使用され、変数がどの型に変換されるかを決定するルールは何ですか?
さまざまなオーバーロードされた関数に必要な変換を比較する場合、 "promotion" は標準の "変換"よりも優れた変換シーケンスと見なされます。すべての算術型は、最大1つの他の型に昇格できます。 (昇格は、printf
のようなCスタイルの可変個引数関数に引数を渡すときにも使用されます。単項_+
_演算子は、_+n
_のような算術式の昇格を強制するために使用できます。 。)
文字型またはbool
ではない整数型の場合、昇格された型は次のとおりです。
int
が元の型のすべての値を表すことができる場合、int
;unsigned int
_が元の型のすべての値を表すことができる場合、_unsigned int
_;あなたの例では、オーバーロードされた関数を比較するとき、「完全一致」が最善ですが、正確に_int8_t
_(または_int8_t&
_または_const int8_t&
_)を取る関数はありません。 _uint8_t
_の昇格された型はint
です。これは、0〜255をはるかに超える範囲をサポートする必要があるためです。そして、明らかにあなたのシステムでは、_int32_t
_はint
のエイリアスであるため、関数void f(int32_t);
は引数のプロモーションのみを必要とします。他の関数はすべて実行可能ですが、引数で整数変換が必要です。したがって、void f(int32_t);
は最適なオーバーロードと見なされます。
したがって、質問に対する技術的な答えは、実装固有であるということですが、int
と_<cstdint>
_型の間の関係のためだけであり、過負荷解決規則のためではありません。
動作は明確に定義されており、but実装固有です。 16ビットのint
では、これは異なっていたでしょう。
標準の特定のルールは次のとおりです。
[[over.best.ics] オーバーロードの解決。 [conv.prom] 統合プロモーション。