2

強く型付けされた列挙で明示的なスコープ解決を無条件に要求する理由は何ですか?

N2347 は、暗黙的な変換がないこと、記憶域の型を指定する機能、および周囲のスコープに名前を注入しないこと (C の遺産としてそれを持っている C++03 のように) である旧式の列挙型との違いを説明しています。

言い換えれば、enum E1 { a, b, c};C++03 のように書くことは、書くことに似ています。

const int a = 1; const int b = 2; const int c = 3;

一方enum E1 class { a, b, c};、C ++ 11の場合は、次のようなものにはるかに似ています

namespace E1 { const int a = 1; const int b = 2; const int c = 3; }

(名前空間を導入せず、いずれの場合も列挙型を定義します)。

さて、たとえば次のようなコード(コンパイルされない)があると仮定して、あいまいさがある場所を一般的に理解していません。

enum class E1 { a, b, c };
enum class E2 { a, b, c }; // allowed now

void foo(E1 e) { ... }
void bar(E2 e) { ... }
void baz(int e) { ... }

foo(a);   // not ambigious: E1 expected, nothing but E1::a possible
bar(a);   // not ambigious: E2 expected, nothing but E2::a possible
baz(a);   // not ambigious: illegal - no name `a` in global scope

E1 x = a; // not ambigious: E1 expected, nothing but E1::a possible

何が起こっているのかを指摘するために、場合によっては (オプションの) 明示的なスコープ解決を歓迎しますが、別の方法でコードを解釈する方法がない場合でも、C++11 が明示的なスコープ解決を必要とする理由がわかりません。

私の意見では、たとえばvoid foo(E1 e);、より多くの意味を持つことを期待するのは合理的ですvoid foo(using enum E1; E1 e);(私の構文はもちろん完全に間違っていますが、アイデアはわかります)。

N2347 にもあるColorandの「古典的な」例を挙げると、 red alertred という色があり、これも異なる数値定数である可能性があります。強い型の保証がなければ、たとえばディスプレイに赤い色を設定するなど、本当に必要なときに alert 数値定数を使用することになると考えられます。または、整数変換と緩い関数宣言により、誰かがオレンジ色を取得するようなものを使用することになると考えられます。Alertyellow|red

それは不可能です。では、私たちは正確に何を防御しているのでしょうか?

4

1 に答える 1

5

フー(a); // あいまいではありません: E1 が期待されますが、E1::a しかあり得ません

式の型がわかっている必要があります。そして、a独立した表現としての使用は曖昧であるため、aどこでもの使用は曖昧です。

式が使用されるコンテキストに応じて意味が変わることは望ましくありません。1 + 1常に同じことを意味します。1 + t同じを使用する場合、常に同じことを意味しますt。同様に、aどこで使用されても常に同じことを意味する必要があります。

C++ で使用されるコンテキストに基づいてソース タイプを推測できるのは、一様な初期化だけです。また、標準では、「braced-init-list」は式ではないと明示的に述べています。aは式なので、式のルールに従います。

于 2012-11-08T17:02:49.197 に答える