C++ 11列挙型クラスが与えられ、いくつかの長くて醜い名前空間内にネストされています。
namespace
long_and_ugly
{
enum class
colour
{
red,
green,
blue
};
}
列挙値でエイリアスを作成できますか? clang ++ 3.5では、次のことを実行できます。
using long_and_ugly::colour; // take all the values into the current namespace
using long_and_ugly::colour::red; // take only 'red' into the current namespace
function_taking_colour_argument( red ); // instead of fully referring to the value
ただし、g ++ 4.9は文句を言います。コードにアクセスできないため、エラーメッセージをコピーできませんが、usingディレクティブまたは宣言の使用法について明示的に文句を言いました。私もこれを試しました:
using red = long_and_ugly::colour::red;
しかし、それも失敗しました。エラーを貼り付けずにごめんなさい。それでも、再現できるはずだと思います。
標準のC++ 11で列挙値のエイリアスを宣言することは可能ですか、それともclang拡張機能を使用していましたか?
もしそうなら、正しい構文は何ですか?
問題は、sing-declarationを指定して使用する場合、enum class内の列挙子を参照しないように標準で規定されていることです。
7.3.3p7
using
宣言[namespace.udecl]
( n3337 )sing-declarationは、スコープ付き列挙子を指定してはなりません。
namespace N {
enum class E { A };
}
using N::E; // legal
using N::E::A; // ill-formed, violation of [namespace.udecl]p7
注:clang
は上記の両方の行を受け入れます。 関連するバグレポートはこちら 。
enum class自体の実際の名前を参照することはまったく問題ありませんが、その列挙型の1つを参照しようとすると形式が正しくありません。
alias-declarationは、type-nameを参照するためにのみ使用できると標準で規定されています。これは、enumeratorが型ではないため、そのような状況で1つを使用することは、形式が正しくありません。
namespace N {
enum class E { A };
}
using x = N::E; // legal, `N::E` is a type
using y = N::E::A; // ill-formed, `N::E::A` isn't a type
「エイリアス」にしたい値で初期化された、選択した名前の定数を持つ定数を宣言できます。
namespace N {
enum class E { A };
}
constexpr N::E x = N::E::A;
int main () {
N::E value = x; // semantically equivalent of `value = N::E::A`
}
種類:
namespace long_and_ugly {
enum class colour
{
red,
green,
blue
};
}
const colour red = long_and_ugly::colour::red;