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

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

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

Q&A

解決済

1回答

4930閲覧

enum classでなくenumを利用する理由

Weapon

総合スコア106

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

0グッド

0クリップ

投稿2021/07/13 07:04

C言語 C++ 戻り値設計について

C言語 C++の戻り値の設計で
"見知らぬ値をint型で返す"
ような設定でなくenum型で返すライブラリなどがモダン?(昔からあると思いますが)だと思います。

例えばグラフィックスライブラリVulkanの戻り値VkResult
GPGPUライブラリCUDA言語のcudaError_t
などが使われています。

enumは強力だと思いますがnamespaceが効かないため、被らないように
VkResultであればVK_ERROR_INITIALIZATION_FAILEDのような長い列挙子を書かなくてはなりません。

仕様かどうかは知らないですがVC++はenumであってもnamespaceのように

VkResult::VK_ERROR_INITIALIZATION_FAILED

と打てばVkResult::の時点で予測変換で表示してくれて便利でコンパイルは通ります。
しかしgccなどではコンパイルできませんよね?

それならnamespaceもあってenumのような長い列挙子も必要がないenum classに軍配が上がると思うのですが
(static_castが必要などはともかく)

(1) 戻り値としてenum classを利用することはあまりないのでしょうか?
(2) デメリットはC言語で利用できないという一点でしょうか?
(3) enum classを使うことでenumより速度が落ちるなどあるのでしょうか? (プリプロセッサーが捌く範囲で関係ないでしょうか?)

(4) また何かこういう戻り値設計が綺麗だったとかこういうガイドラインがあるとかありましたら教えてください

環境

VC++14
g++14
(特別にバージョンは問わない)

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

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

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

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

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

neconekocat

2021/07/13 07:15

まずenum classが登場したのはいつでしょう? 少なくともC言語には無関係なお話です。
ttact

2021/07/13 07:55

プリプロセッサはC/C++の文法を解釈しません。よってenumとenum classの違いも認識しません。C/C++の文法を解釈するのはコンパイラの役割です。 enumとenum classは実装速度に違いは出ません。出力されるバイナリやアセンブリコードで比較してみると良いと思います。
guest

回答1

0

ベストアンサー

歴史的な事情が大きいでしょう。
enum class が規格化されたのはたったの10年前です。それより前から提供されているライブラリなどは enum class を使えませんでしたし、emum を enum class に変更するとソース互換性がなくなってしまうのでわざわざ変更したりしないでしょう。

(1) 戻り値としてenum classを利用することはあまりないのでしょうか?

新しいコードであれば、enum より enum class を使うことが多いでしょう。

(2) デメリットはC言語で利用できないという一点でしょうか?

●少々コードが長くなることがあります。

cpp

1 2class Foo { 3 enum Type { 4 kApple, 5 kOrange 6 }; 7} 8 9class Bar { 10 enum class Type { 11 kApple, 12 kOrange, 13 }; 14};

前者は Foo::kApple で参照できますが、後者はBar::Type::kAppleと書かないといけません。
(前者はクラス内で定義されているので、長い名前を付ける必要がない)

●enum classでは簡単に整数演算ができないので、ビットフラグを表現するのは現実的ではありません。

cpp

1 2enum class FooFlags { 3 kFlag1 = 1 << 0, 4 kFlag2 = 1 << 1, 5 kFlag3 = 1 << 2, 6}; 7 8FooFlags flags = ...; 9if (flags & FooFLags::kFlag2) { // できない

(3) enum classを使うことでenumより速度が落ちるなどあるのでしょうか? (プリプロセッサーが捌く範囲で関係ないでしょうか?)

ありません。

投稿2021/07/13 07:24

編集2021/07/13 10:06
int32_t

総合スコア21695

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

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

fana

2021/07/13 07:53

戻り値の話とは関係ないですが, bitフラグのフラグ群の値を enum で書いちゃうような場合, enum class だと何やら面倒っぽいですね. (ググると,必要なoperator群をマクロだのtemplateで書くだのいう話が…)
int32_t

2021/07/13 08:02

たしかに、enum class でビットフラグを表現するのは現実的ではないですね。そこが理由で enum を使うケースもありそうです。
int32_t

2021/07/13 10:06

ビットフラグについて回答に追記しました。
fana

2021/07/13 10:12

話の範囲が「戻り値」に限定されているようにも見えるので,書く場所を既存内容とは分けてofftopic気味な感じにしても良いかもしれません. (フラグの組み合わせ値を返す場合には,戻り値の型をenumにはしないように思うので)
Weapon

2021/07/13 12:29

興味深い話をありがとうございます。 enum classを HRESULTのSUCCEEDED()などのように判定するなり operator overloadするなり使っていこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問