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

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

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

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

C++

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

Q&A

解決済

3回答

13154閲覧

C++ クラスのメンバ変数にループでアクセスするには

sin_250

総合スコア112

C

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

C++

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

0グッド

0クリップ

投稿2017/05/18 12:17

お世話になります。質問させていただきます。

C++で、クラスのメンバ変数にforループでアクセスする方法はあるでしょうか、という質問になります。

例えば、

cpp

1enum Sex {MAN, WOMAN}; 2class Human { 3public: // 記載スペースの節約のため全部public 4 Sex sex; 5 int age; 6 bool married; 7}; 8 9int main(void) { 10 Human taro, yuki; 11 taro.sex = MAN, taro.age = 23, taro.married = false; 12 yuki.sex = WOMAN, yuki.age = 19, yuki.married = false; 13 14 /* taroとhanakoのメンバ変数を比較して、同じだったら「一緒だね!」と表示したい */ 15 16 return 0; 17}

(もちろん話をデフォルメしております)
ここで、taroとyukiのメンバ変数の比較は、数が少なければ if をたくさん書けば済みますが(上記の例なら3つ)、
実際にはメンバ変数の数が20個以上あって型もマチマチだと思ってください。
このようなとき、 if を20個書かずにスマートに解決したいです。下のような感じで。

cpp

1for (int i=0; i < Human.itemsNum(); i++) { 2 if (taro.item[i] != yuki.item[i]){ 3 cout << "一緒だね!" << endl; 4 } 5}

また訳あってC++11は使用不可です。。。

何か良い方法はございますでしょうか。
よろしくお願い申し上げます。

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

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

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

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

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

guest

回答3

0

こんにちは。

残念ながらできません。
例えばC#のリフレクションのようにクラス定義を動的に変更するのは流石に言語思想上無理とは思いますが、参照するだけならさせてくれてもいいじゃないか!とは思います。

私はTheolizerと言うシリアライザを開発してますが、それではclangと言うC++コンパイラに付属の構文解析ツールlibToolingを使ってユーザ・クラスのソース・コードを解析してメンバ変数のリストを自動生成することで、forで処理できるようにしてます。

でも、ターゲットがシリアライザだからできたのだと思います。
様々な型の変数に対して任意の処理を書くことってたいへんだから、メンバ変数リストにアクセスできるようにしてもあまり使う人が居ないから標準対応しないのかも。

投稿2017/05/18 13:08

Chironian

総合スコア23272

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

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

GrayWingAliance

2017/05/18 13:16

あぁ、なるほど、C#のイテレータとC++のイテレータは全く別物なのですね!
Chironian

2017/05/18 13:59

いえ、イテレータは例えば配列に入っているデータを列挙する際に使う変数という意味では大差ないです。 C#は、GetProperties()を使ってプロバティ(メンバ変数のようなもの)のリストとしてPropertyInfoの配列を返却します。C++に無いのはこのGetProperties()のような機能です。 もし、メンバ変数の配列を返却する機能があれば、それを列挙するのにC#と同様インテレータを使うことができます。
sin_250

2017/05/20 01:22

大変勉強になりました。ありがとうございました。
guest

0

ベストアンサー

C++で、クラスのメンバ変数にforループでアクセスする方法はあるでしょうか

(Chironianさん回答と同じですが)C++言語ではリフレクションをサポートしないため、素直な方法では不可能です。

Boost.Fusionライブラリを用いれば、似たようなことを実現できますが、本当にその方法が好ましいかは状況次第かと思います。


ここで、taroとyukiのメンバ変数の比較は、[...]
このようなとき、 if を20個書かずにスマートに解決したいです。

構造体同士の等値比較を行いたいのであれば、operator==演算子オーバーロードを定義するのが自然です。同関数定義では結局メンバ変数を列挙しないといけませんが、利用側コードはすっきりします。

C++

1// クラス定義 2struct Human { 3 Sex sex; 4 int age; 5 bool married; 6 7 bool operator==(const Human& a, const Human& b) { 8 return (a.sex == b.sex) && (a.age == b.age) && (a.married == b.married); 9 } 10}; 11 12// 利用側コード 13Human taro, yuki; 14... 15if (taro == yuki) {...}

投稿2017/05/19 05:59

編集2017/05/19 06:01
yohhoy

総合スコア6189

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

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

Chironian

2017/05/19 07:06 編集

一般解としてはBOOST_FUSION_ADAPT_STRUCT()のような方法でメンバ変数リストを定義するのが実的ですね。このようなものがあるということは、やはり需要はあるんですね。 しかし、このマクロ、凄まじいテクニックを使ってそうですね。今なら可変長引数使えばできそうですが、可変長引数無しでできるとはびっくりです。
sin_250

2017/05/20 01:23

ご回答有り難うございました。ほか言語の勉強にもなり、視野が広がりました。ありがとうございました。
guest

0

C++03てイテレータ使えないんでしたっけ?

投稿2017/05/18 12:32

GrayWingAliance

総合スコア218

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

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

sin_250

2017/05/18 12:37

ご返信有り難うございます。std::vectorなどでiteratorが使えることは存じておりますが、 このようなケースで適用できるのでしょうか?
GrayWingAliance

2017/05/18 13:18

なんか私の勘違いで、舌の方の回答が正しそうです。 C#と少し混同していました。失礼いたしました。
sin_250

2017/05/20 01:22

いえいえ、ご回答有り難うございます! 無理!ということがわかってすっきりしたというか、そういうことが必要にならないように設計しないといけないんだなと 勉強になりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問