C/C++のenum

yuki
記事: 5
登録日時: 14年前

C/C++のenum

投稿記事 by yuki » 14年前

型付きの定数を宣言・定義するときはenumを使うと思います。
#defineで定義するときと違うのは、型とスコープがあるということなのですが、
ずっと思っていたことがあります。

なんで定数のスコープが外にあるの…

つまりは、

CODE:

enum EnumTest
{
    ENUMTEST_ONE = 1,
    ENUMTEST_TWO,
    ENUMTEST_THREE,
};

EnumTest  test = ::ENUMTEST_ONE;
こういうことです。
名前空間も汚れるし(グローバルな空間に放り投げられる)、
定数名にいちいち列挙型名をつけておかないとグローバルな空間で被るかもしれない。
しかも「EnumTest test = EnumTest::ENUMTEST_ONE;」みたいな書き方が出来ない。
まぁ結局定数がグローバルな空間にあるから、EnumTestの中にはそんな識別子ありませんよ、ってことなのでしょうけど。

なぜenumもちゃんとstructの仲間に入れてあげなかったのか。
理想としては、

CODE:

enum EnumTest
{
    ONE = 1,
    TWO,
    THREE,
};
EnumTest test = EnumTest::ONE;
こう書きたいんです。
こっちのほうが理に適っています。
名前空間も汚れません。
本当になんでこんな仕様になってしまったのか…
詳しいところをご存知の方はご教示ください。

ということで打開策なのですが、
C++ならば素直にstructでスコープを作る

CODE:

struct EnumTest
{
    enum
    {
        ONE = 1,
        TWO,
        THREE,
    };
};
int test = EnumTest::ONE;
でも型がつけられない。
ので、中の無名enumをenum enum_tみたいにすれば、

CODE:

EnumTest::enum_t test = EnumTest::ONE;
こう書けて丁度良いかも?
前方宣言はできませんが。

C++0xを使えということでしょうか…

アバター
GRAM
記事: 164
登録日時: 14年前

RE: C/C++のenum

投稿記事 by GRAM » 14年前

structで囲ったりしたら

CODE:

void SomeFunction(EnumTest hoge){
      if(hoge == ONE) printf("hoge == ONE");
      return;
}
みたいなことができなくなってしまうのでは?
この構文からして列挙型そのものにスコープがあってはならないと思うのですが・・・
(すくなくとも構造体やクラスの仲間ではないと思います)

もしhoge == EnumTest::ONEだとしたらONEはいったいなんなのでしょう?と思ったのですが(全然的を射てなかったらすみません)

追記:すみません。コードタグがおかしかったので書き換えました
最後に編集したユーザー GRAM on 2011年3月01日(火) 16:51 [ 編集 1 回目 ]

yuki
記事: 5
登録日時: 14年前

RE: C/C++のenum

投稿記事 by yuki » 14年前

コメントありがとうございます。
GRAM さんが書きました:structで囲ったりしたら

CODE:

void SomeFunction(EnumTest hoge){
      if(hoge == ONE) printf("hoge == ONE");
      return;
}
みたいなことができなくなってしまうのでは?
この構文からして列挙型そのものにスコープがあってはならないと思うのですが・・・
(すくなくとも構造体やクラスの仲間ではないと思います)
もしhoge == EnumTest::ONEだとしたらONEはいったいなんなのでしょう?と思ったのですが(全然的を射てなかったらすみません)
エントリーに書いてあるとおり、structで囲った中の無名enumをenum_tに変えると、EnumTest::enum_t型として変数宣言出来ます。
そして定数(ONEやTWO)は、EnumTest内にスコープを持っているので、EnumTest::ONEとすべきです。

CODE:

void SomeFunction(EnumTest::enum_t hoge){
      if(hoge == EnumTest::ONE) printf("hoge == EnumTest::ONE");
      return;
}
要するに、Javaの列挙子と似たようなことをしたかったのです。

アバター
GRAM
記事: 164
登録日時: 14年前

RE: C/C++のenum

投稿記事 by GRAM » 14年前

yuki さんが書きました: エントリーに書いてあるとおり、structで囲った中の無名enumをenum_tに変えると、EnumTest::enum_t型として変数宣言出来ます。
ああ、そういう意味だったんですね^^;誤解でしたスミマセン。
自分が思ったのは::の先にあるのは普通それがどんな型かわかるもの(変数であれ関数であれtypedefであれ)じゃないかなぁと思ったわけです。
でもenumでEnumTest::ONEとしちゃうとONEやTWOはいったい何なんでしょう?と思っちゃったわけです。
スコープを外にとればONEはEnumTestだと解釈できるんじゃないかなぁと。(hoge == Oneもそんな感じにとらえてました)

まあJavaがそうなってるんじゃ、実際標準委員会がなに考えたのかはちょっとわかんないですけど

ISLe
記事: 2650
登録日時: 14年前

Re: C/C++のenum

投稿記事 by ISLe » 14年前

従来型enumはC言語の文法との互換性を重視したのだと思います。

namespaceを使えば

CODE:

namespace EnumTest
{
	enum EnumTest_t
	{
		ONE = 1,
		TWO,
		THREE,
	};
}
EnumTest::EnumTest_t test = EnumTest::ONE;
というふうに書けますけど、enum classのほうがよりスマートですね。