質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
列挙型

データ型の一種で、要素・メンバなど名前のある値や、型の列挙子によって構成されます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2487閲覧

C++でクラス名と同名の列挙子を定義したい

nicoyou

総合スコア129

列挙型

データ型の一種で、要素・メンバなど名前のある値や、型の列挙子によって構成されます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/05/13 13:30

C++でクラス名と同名のスコープ有列挙子を定義することは可能でしょうか?
調べても出てこなかったので不可能だと思っているのですが、もし可能ならば方法を教えていただきたいです
以下の様なクラスを定義したいです

C++

1enum class A 2{ 3 e1 4} 5 6class A 7{ 8public: 9 A(A n); 10 ~A(); 11 12private: 13 14}; 15 16A::A(A n) 17{ 18} 19 20A::~A() 21{ 22}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasumichi

2020/05/13 14:10

そうしたい理由は何でしょうか?
nicoyou

2020/05/13 14:22

列挙子で定義された状態を保存しておくクラスを作るうえで型名と列挙子の名前が同じほうが分かりやすいからです 例えばですが、変数名.next()で状態を一定の法則に従って変化させるなどの関数があるものです
nicoyou

2020/05/13 14:35

"class"というクラスを作りたいわけではありません 列挙子と同名のクラスです
Yasumichi

2020/05/13 14:40

C++11 から 「enum」 とは別に「enum class」というのが存在するようです。 > cateye さん
Yasumichi

2020/05/13 14:47

個人的には、"enum class 名前" と "class 名前" の名前を同じにしたいということで良いのですよね? 個人的には、「列挙型名」+Iterator みたいな名前の方が分かりやすい気がしますが…。 enum class 名前 ← スコープ付き列挙型 { 列挙子 };
nicoyou

2020/05/13 14:50

はい、そうです このようにすれば可能ではないかと一つ思いついたのですが、ダメでした static enum myenumA : int{}; class A { public: int x; enum : myenumA { e1 }; A(myenumA n) { x = n; } };
cateye

2020/05/13 14:50

了解^^; 勉強に成りました。
guest

回答2

0

ベストアンサー

同じ名前空間に同じ名前の異なる複数の定義が 仮にどうにかしてできたのだとしても,
その名前を使っている箇所でことごとく「それはどれのこと?」って話になるわけで,
質問者が言う「わかりやすい」とは真逆な世界にまっしぐらであるとしか思えない.

例えば,質問コード内のコンストラクタ

A(A n);

の引数って,どっちなんですかね? って定まらないでしょう.


で,「enumとclassの2つ」じゃなくて,classだけにしたらダメなんでしょうか.
状態管理をclassが行うとすれば,enumの存在意義が謎なので,例えば以下のような感じで.

C++

1class A 2{ 3public: //enumの代替 4 static A one(){ return A(1); } 5 static A two(){ return A(2); } 6 static A three(){ return A(3); } 7 8public: 9 A( const A &a ) : m_value( a.m_value ) {} 10 11private: //private : 適当な値で初期化はできない 12 A( int value ) : m_value( value ) {} 13 14private: 15 int m_value; 16};

投稿2020/05/14 01:53

fana

総合スコア11632

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nicoyou

2020/05/14 02:21 編集

ご回答ありがとうございます >質問者が言う「わかりやすい」とは真逆な世界にまっしぐらであるとしか思えない. クラス内で無名列挙子を定義し、それを引数にとるものを稀に見かけますが、 整数を渡せてしまうと何を渡しているのかわからないようになるため、列挙子のみを受け付けるようにしたかったためです A temp(A::enum1); の様な表記になるのでややこしくはならないかなと ( そもそも個人のみのプログラムなので、他人(途中からプログラムを読んだ人)が分かりやすいかどうかはあまり意識していませんでした ) >enumの存在意義が謎 複数の状態は数字とは関係がないので、整数で初期化や比較をしてしまうと後からコードを見た時に何をやっているのかわかりにくくなってしまうからです if (temp == A::enum1) 確かに関数名で代用することは可能ですね... ただ、数が多いと大変なので、その場合はあきらめて以下のようにしようと思っています class A { enum class e { } } A::e::enum1
fana

2020/05/14 02:49

> //enumの代替 と書いたことに語弊があったかな. 「enum値とかint型の数値を用いてclass Aの内側での状態区別方法を実装するかどうか」はどうでもよくて(どうせ外側からは見えないし,その「実装上の値」を外側では全く扱わない), 要は,class A(のインスタンス)が「状態」を表す,という話.
fana

2020/05/14 02:53

one()とかtwo()とかいう名前で書いたのが良くなかったかな. static A XX_State(){ XX状態を表すA型インスタンスを生成して返す } static A YY_State(){ YY状態を表すA型インスタンスを生成して返す } という話.
nicoyou

2020/05/14 03:54

>one()とかtwo()とかいう名前で書いたのが良くなかったかな. >> //enumの代替 恐らく私の説明が良くないのだと思いますが、理解はしていました 頂いたサンプルでも同じことが出来るというのは、確かにと思ったのですが 一般的ではなさそうな書き方で、同名の名前を優先するぐらいなら、一文字のenumを使用したほうが まだましだと考えたので上の様な返信をしました このような書き方ができるということは覚えておこうと思います
nicoyou

2020/05/14 03:57

質問の回答はおそらく不可能ということと、代わりのアイデアを書いていただいたのでBAにさせていただきました
guest

0

意味を取り違えていたらすみませんが、こういうことでしょうか。

cpp

1#include <iostream> 2 3class A { 4 int x; 5 enum { 6 e1, 7 e2, 8 e3 9 }; 10 11public: 12 A(){ 13 x = e1; 14 } 15 void next() { 16 x++; 17 } 18 19 void out() { 20 std::cout << x << std::endl; 21 } 22}; 23 24int main() { 25 A a; 26 a.next(); 27 a.out(); 28 a.next(); 29 a.out(); 30} 31

投稿2020/05/13 14:32

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nicoyou

2020/05/13 14:40

ご回答ありがとうございます ほとんどその通りなのですが、コンストラクタ(またはset関数)で列挙子を用いて初期化したいです 少しコードを変更すると以下の様なことがしたいのですが、これだと列挙子以外の数を代入できてしまうので class enum のように列挙子のみしか渡せないようにしたいです (キャストすれば強制的に代入することは出来ますが、わざわざそんなことはしないので...) '''C++ class A { public: int x; enum { e1, e2, e3 }; A(int n) { x = n; } void next() { x++; } void out() { std::cout << x << std::endl; } }; int main() { A a(A::e1); a.next(); a.out(); a.next(); a.out(); } '''
退会済みユーザー

退会済みユーザー

2020/05/13 14:54

把握しました、が、僕はご要望を解決する手法が思いつかないですね。 別名で作ってやれば一応は叶うのですが(列挙型の型名は意識しなくてすみそうだが質問からは逸れてしまう)…お力になれずすみません。 ```cpp #include <iostream> class A { public: int x; enum A_ { e1, e2, e3 }; A(A_ n) { x = n; } void next() { x++; } void out() { std::cout << x << std::endl; } }; int main() { A a(A::e1); //A b(1); // エラー a.next(); a.out(); a.next(); a.out(); } ```
nicoyou

2020/05/13 14:59

了解です、やはりこのような暴挙は行えないんですかね(笑) >別名で作ってやれば一応は叶うのですが 最終手段としてそうしようと思っています...
退会済みユーザー

退会済みユーザー

2020/05/13 15:05

同じ名前空間に同じ名前で定義が難しそうな気がします… 名前空間を別にしてやれば出来そうですが、これもまた逸れますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問