2013-07-23 11 views
7

次のコードでは、f(unsigned)の代わりにf(int)のオーバーロードが選択されています。 clang 3.0とgcc 4.8でテストされています。enum - > intはenum - > unsignedよりも優れた変換をします。

enum E 
{ 
}; 

E f(int); 
int f(unsigned); 

E e = f(E(0)); 

標準の私の読書enum -> intenum -> unsignedの両方が唯一の積分変換を含んで、同一の標準変換シーケンスであることを考えるように私をリードしています。

[conv.integral]列挙型の右辺値は、整数型の右辺値に変換できます。

[over.best.ics]によれば、整数変換のみを含む標準変換シーケンスのランクは「変換」です。

[over.ics.rank]以下のいずれかのルールが適用されない限り、同じ形の二つの暗黙的な変換配列が区別できない変換配列である:[...]言及したルールの

なし思えません2つの標準変換シーケンスを比較するときに適用します。

私には何が欠けていますか?

+0

'enum'はデフォルトで' int'を基本にしていますので、その変換はより良いと思います。 'short'や' char'を使うように言うと、あなたが期待しているあいまいさを得るでしょう。 –

+0

['std :: underlying_type'](http://en.cppreference.com/w/cpp/types/underlying_type)を使用して、列挙型の根底にある型を特定する必要があります。 –

+0

インテグラルプロモーション。それは実際にインテグラルコンバージョンではありません。 [conv.prom] – dyp

答えて

6

C++ 11:

[conv.prom]/3

基底型固定されていない対象範囲外の列挙型(7.2)のprvalueがのprvalueに変換することができます。 列挙のすべての値(即ち、B maxまでの範囲bの最小の値は7.2で説明したように)表すことができ、以下のタイプの最初:intunsigned intlong intunsigned long intlong long int、又はunsigned long long intを。

そして(強調鉱山)、[over.ics.rank]/4:

標準変換配列は、それらのランクによって順序付けされる:完全一致がより良好変換でありますプロモーションはコンバージョンよりも優れたコンバージョンです

したがって、発現f(E(0))上のオーバーロード解決のために、過負荷E f(int);積分変換がint f(unsigned);ために必要な、より高いランクを有する(([conv.prom]介しEからintに、)だけ積分促進を必要と[conv.integral]を介してEからunsigned)。 C++ 03


最初の引用は若干異なるものの、議論は、同じである: [conv.prom]/2

タイプwchar_tの右辺値(3.9.1 )または列挙型(7。2)は、基底型のすべての値を表す次の型の最初の値(int,unsigned intlong、またはunsigned long)に変換できます。

[over.ics.rank]/4は同じです。

+0

は、C++ 03を参照するのに私の役目をしています! – willj

+0

それを "C++ 03をスキミングするために私の役に立つ";) – willj

+0

@willj私が知っているところから、Integral Promotionは広く知られている機能ではありません。 – dyp

関連する問題