C ++にリフレクションがないのはなぜですか?


337

これはやや奇妙な質問です。私の目的は、言語設計の決定を理解し、C ++での反映の可能性を特定することです。

  1. なぜC ++言語委員会は言語でのリフレクションの実装に向かわなかったのですか?仮想マシン(Javaなど)で実行されない言語では、反射が難しすぎますか?

  2. C ++のリフレクションを実装するとしたら、どのような課題がありますか?

リフレクションの使用法はよく知られていると思います。エディターをより簡単に作成でき、プログラムコードが小さくなり、単体テスト用にモックを生成できるなどです。しかし、リフレクションの使い方についてもコメントしていただければ幸いです。

回答:


631

C ++でのリフレクションにはいくつかの問題があります。

  • 追加するのは大変な作業であり、C ++委員会はかなり保守的であり、成果が出ると確信しない限り、根本的な新機能に時間を費やさないでください。(.NETアセンブリに似たモジュールシステムを追加する提案があり、それがいいと思うという一般的な合意はあると思いますが、現時点では最優先事項ではないため、かなり後になるまで押し戻されました。 C ++ 0x。この機能の動機は#includeシステムを取り除くことですが、少なくとも一部のメタデータも有効にします)。

  • 使用しないものについては支払いません。これは、C ++の基礎となる必須の基本設計哲学の1つです。メタデータが必要ない場合でも、コードでメタデータを保持する必要があるのはなぜですか?さらに、メタデータを追加すると、コンパイラーが最適化できなくなる可能性があります。メタデータがまったく必要ない可能性があるのに、コードにそのコストを支払う必要があるのはなぜですか?

  • これはもう一つの大きなポイントに私たちをリード:C ++は作る非常にコンパイルされたコードについてのいくつかの保証を。コンパイラーは、結果として得られる機能が期待どおりのものである限り、好きなことをほとんど実行できます。たとえば、クラスが実際に存在する必要はありません 。単純なテンプレートコードでもかなりの数のテンプレートのインスタンス化を作成する傾向があるため、コンパイラーはそれらを最適化して削除し、実行するすべてのことをインライン化できます。C ++標準ライブラリ、この積極的な最適化に依存しています。ファンクタは、オブジェクトのインスタンス化と破棄のオーバーヘッドを最適化できる場合にのみ機能します。 operator[]演算子全体をインライン化して、コンパイルされたコードから完全に削除できるため、ベクトルでのパフォーマンスは、生の配列のインデックス作成に匹敵します。C#とJavaは、コンパイラーの出力に関して多くの保証をします。C#でクラスを定義すると、そのクラス結果のアセンブリに存在します。私がそれを使ったことがないとしても。そのメンバー関数へのすべての呼び出しがインライン化されたとしても。クラスはそこにある必要があるので、リフレクションがそれを見つけることができます。これの一部は、バイトコードにコンパイルするC#によって緩和されます。つまり、JITコンパイラ初期のC#コンパイラができなくても、必要に応じてクラス定義とインライン関数を削除します。C ++では、コンパイラは1つだけで、効率的なコードを出力する必要があります。C ++実行可能ファイルのメタデータを検査することが許可されている場合、定義されたすべてのクラスが表示されるはずです。つまり、コンパイラーは、必要でない場合でも、定義されたすべてのクラスを保持する必要があります。

  • そして、テンプレートがあります。C ++のテンプレートは、他の言語のジェネリックのようなものではありません。テンプレートのインスタンス化ごとに新しいタイプが作成されます 。std::vector<int>はとは完全に別のクラスです std::vector<float>。これは、プログラム全体でさまざまなタイプの合計になります。私たちの反射は何を見るべきですか?テンプレート std::vector?しかし、それは実行時に何の意味もないソースコード構造なので、どうすればよいのでしょうか。個別のクラスstd::vector<int>とを確認する必要が あり std::vector<float>ます。そして std::vector<int>::iteratorstd::vector<float>::iteratorと同じconst_iterator等々。また、テンプレートのメタプログラミングに入ると、何百ものテンプレートがインスタンス化され、そのすべてがコンパイラーによってインライン化および削除されます。コンパイル時のメタプログラムの一部として以外は、意味がありません。これらの何百ものクラスすべてがリフレクションから見えるはずですか?そうでなければ、私が定義したクラスが実際にそこにあることさえ保証されなければ、リフレクションは役に立たないためです。そして、副次的な問題は、インスタンス化されるまでテンプレートクラスが存在しないことです。を使用するプログラムを想像してみてくださいstd::vector<int>。私たちの反射システムは見ることができますstd::vector<int>::iteratorか?一方で、あなたは確かにそう期待するでしょう。これは重要なクラスであり、で定義されstd::vector<int>います。メタデータに存在します。一方、プログラムこのイテレータクラステンプレートを実際に使用しない場合、その型はインスタンス化されないため、コンパイラは最初からクラスを生成していません。また、ソースコードにアクセスする必要があるため、実行時に作成するには遅すぎます。

  • そして最後に、リフレクションはC ++の場合ほどC ++ほど重要ではありません。その理由は、テンプレートのメタプログラミングです。それはすべてを解決することはできませんが、他の方法でリフレクションに頼る多くの場合、コンパイル時に同じことを行うメタプログラムを作成することが可能です。 boost::type_traits簡単な例です。タイプについて知りたい Tですか?を確認してくださいtype_traits。C#では、リフレクションを使用してタイプの後に釣り回る必要があります。リフレクションは依然としていくつかの点で有用です(私が見ることができる主な用途はメタプログラミングでは簡単に置き換えることができず、自動生成されたシリアル化コード用です)が、C ++にはかなりのコストがかかり、それほど頻繁には必要ありません。他の言語です。

編集: コメントへの応答:

cdleary:はい、デバッグシンボルは実行可能ファイルで使用される型に関するメタデータを格納するという点で、同様のことを行います。しかし、彼らは私が説明した問題にも苦しんでいます。これまでにリリースビルドのデバッグを試みたことがあれば、私が何を意味しているのかわかるでしょう。ソースコードでクラスを作成したところ、最終的なコードでインライン化された大きな論理的なギャップがあります。役立つものにリフレクションを使用する場合は、より信頼性が高く一貫性のあるものにする必要があります。現状では、コンパイルするたびに型は消滅し、消えてしまいます。小さな細部を変更すると、コンパイラーは、応答として、インライン化されるタイプとインライン化されないタイプを変更することを決定します。あなたがしているときに、そこからどのように有用なものを抽出しますか 最も関連性の高いタイプがメタデータで表されることが保証されていませんか?あなたが探していたタイプは最後のビルドにあったかもしれませんが、今ではなくなっています。そして明日、誰かが小さな無害な関数への小さな無害な変更をチェックインします。これにより、型は十分に大きくなり、完全にインライン化されないため、再び元に戻ります。これはまだデバッグシンボルに役立ちますが、それ以上のものではありません。これらの条件の下でクラスのシリアル化コードを生成しようとするのは嫌です。それ以上ではありません。これらの条件の下でクラスのシリアル化コードを生成しようとするのは嫌です。それ以上ではありません。これらの条件の下でクラスのシリアル化コードを生成しようとするのは嫌です。

エヴァン・テラン:もちろん、これらの問題解決される可能性があります。しかし、それは私のポイント1に戻ります。それは多くの作業を必要とし、C ++委員会は彼らがより重要だと感じている多くのことを持っています。他の機能を犠牲にしてそれに集中することを正当化するのに十分な大きさのC ++のリフレクション(およびリミテッド)を得るメリットは本当に大きいのでしょうか?QTのようなライブラリやプリプロセッサを介して既に(ほとんど)実行できるコア言語を機能に追加することには、本当に大きなメリットがありますか?おそらく、そのようなライブラリが存在しなかった場合よりも、必要性はそれほど緊急ではありません。ただし、具体的な提案については、テンプレートで禁止すると完全に役に立たなくなると思います。たとえば、標準ライブラリではリフレクションを使用できません。どのような反射がありませんかstd::vector?テンプレートはC ++の重要部分です。テンプレートでは機能しない機能は基本的に役に立ちません。

しかし、そうです、何らかの形のリフレクションを実装できます。しかし、それは言語の大きな変化になるでしょう。現在のように、型はコンパイル時の構成要素です。それらはコンパイラーの利益のために存在し、それ以外にはありません。コードがコンパイルされると、クラスなくなります。自分を伸ばすと、関数はまだ存在していると主張することができますが、実際には、たくさんのジャンプアセンブラ命令と多くのスタックプッシュ/ポップがあります。そのようなメタデータを追加する場合、何もする必要はありません。

しかし、私が言ったように、コンパイルモデルの変更、自己完結型モジュールの追加、選択タイプのメタデータの保存、#includes をいじる必要なく他のモジュールがそれらを参照できるようにする提案があります。これは良い出発点であり、正直に言うと、標準委員会があまりにも大きな変更であるという提案を捨てなかったのには驚いています。それでおそらく5-10年で?:)


2
これらの問題のほとんどは、すでにデバッグシンボルで解決する必要はありませんか?(あなたが述べたインライン化と最適化のために)それはパフォーマンスがあるとは限りませんが、デバッグシンボルが何をするかによってリフレクションの可能性を可能にすることができます。
cdleary 2008

2
あなたの最初のポイントについてのもう一つのこと:私が知る限り、C ++実装にリフレクションを追加しようとした人はいません。良い経験はありません。委員会は、おそらく、特に後に、リードを取ることに消極的になるだろうexportvector<bool>
David Thornley、

18
C ++にランタイムリフレクションを含めるべきではないことに同意します。しかし、コンパイル時リフレクションには上記の問題のいくつかがあり、特定のクラスで実行時リフレクションを構築するために使用することができます。テンプレートを介してクラスのn番目のメソッドとn番目の親のタイプと名前および機能にアクセスできるか?そして、コンパイル時にそのような数を取得しますか?CRTPベースの自動リフレクションを実行可能にしますが、使用していないものに対しては誰も支払いません。
Yakk-アダムNevraumont

15
3番目のポイントは、多くの点で最も重要です。C++は、メモリにコストがかかるプラットフォームでスタンドアロンコードを作成するのに適しています。未使用のコードをいくつか削除すると、プログラムが$ 2.50のマイクロコントローラーではなく、$ 2.00のマイクロコントローラーに収まるようになり、コードが1,000,000単位になる場合、そのコードを削除すると$ 500,000を節約できます。リフレクションがなければ、静的分析は到達不能コードの90%以上を特定できることがよくあります。Reflectionが許可されている場合、Reflectionを介して到達できるものは、たとえ90%が到達できないとしても、到達可能であると想定する必要があります。
スーパーキャット2013年

2
comiteeによって容易に向上させることができる何かが間違いなく存在し、それは最終的にことを白に黒と言うことですtypeinfoname()機能が未定義のプログラマーではなく、何かによってで入力した名前を返さなければなりません。また、列挙子の文字列指定子も指定してください。これは、工場などを作る際に支援し、シリアライズ/デシリアライゼーションのため、実際に非常に重要である
v.oddou

38

リフレクションでは、タイプに関するいくつかのメタデータをクエリ可能な場所に保存する必要があります。C ++はネイティブマシンコードにコンパイルされ、最適化のために大幅な変更が加えられるため、アプリケーションの高レベルのビューはコンパイルのプロセスでかなり失われ、その結果、実行時にそれらをクエリすることはできません。Javaおよび.NETは、仮想マシンのバイナリコードで非常に高レベルの表現を使用して、このレベルのリフレクションを可能にします。ただし、一部のC ++実装では、実行時タイプ情報(RTTI)と呼ばれるものがあります。これは、リフレクションのストリップバージョンと見なすことができます。


15
RTTIはC ++標準です。
Daniel Earwicker 2008

1
ただし、すべてのC ++実装が標準であるわけではありません。RTTIをサポートしない実装を見てきました。
Mehrdad Afshari、

3
そして、RTTIをサポートするほとんどの実装は、コンパイラオプションを介してそれをオフにすることもサポートしています。
マイケルコーン

21

すべての言語が他のすべての言語のすべての機能を組み込むことを試みるべきではありません。

C ++は基本的に、非常に高度なマクロアセンブラです。これは(伝統的な意味で)C#、Java、Objective-C、Smalltalkなどの高級言語ではありません。

仕事ごとに異なるツールを用意するとよいでしょう。ハンマーしかない場合は、すべてが釘などのように見えます。スクリプト言語を使用することは、一部のジョブでは役立ち、反射型OO言語(Java、Obj-C、C#)は、別のクラスのジョブで役立ちます。マシンに近い効率的なベアボーンは、さらに別のクラスのジョブ(C ++、C、アセンブラー)に役立ちます。

C ++は、アセンブラーテクノロジーを信じられないほどのレベルの複雑さ管理に拡張するという驚くべき仕事と、人間にとってプログラミングをより大きく、より複雑なタスクをはるかに可能にする抽象化を行います。しかし、厳密に高レベルの観点から問題に取り組んでいる人(Lisp、Smalltalk、Java、C#)に最適な言語であるとは限りません。問題の解決策を最適に実装するためにこれらの機能を備えた言語が必要な場合は、そのような言語を作成してくれたすべての人に感謝します。

しかし、C ++は、何らかの理由で、コードと基盤となるマシンの操作との間に強い相関関係が必要な人向けです。その効率、デバイスドライバのプログラミング、低レベルのOSサービスとのやり取りなど、C ++はこれらのタスクにより適しています。

C#、Java、Objective-Cはすべて、その実行をサポートするために、はるかに大規模で豊富なランタイムシステムを必要とします。そのランタイムは、問題のシステムに配信する必要があります-ソフトウェアの操作をサポートするためにプレインストールされています。そして、その層は、そのプラットフォームで動作するように他の言語によってカスタマイズされた、さまざまなターゲットシステム用に維持する必要があります。そして、その中間層-ホストOSとコードの間のアダプティブレイヤー-ランタイムは、ほとんどの場合、効率が#1であるCまたはC ++のような言語で記述され、ソフトウェアとハ​​ードウェア間の正確な相互作用を予測可能に理解することができます。理解し、最大のゲインに操作されました。

私はSmalltalk、Objective-C、およびリフレクション、メタデータ、ガベージコレクションなどを備えた豊富なランタイムシステムが大好きです。これらの機能を利用するためのすばらしいコードを書くことができます。しかし、それは単にスタックの上位層であり、下位層に置かれる必要のある層であり、それ自体が最終的にOSとハードウェア上に置かれる必要があります。そして、その層の構築に最適な言語が常に必要です。C++ / C / Assembler。

補遺:C ++ 11/14は、C ++の機能を拡張して、より高いレベルの抽象化とシステムをサポートしています。スレッド化、同期、正確なメモリモデル、より正確な抽象的なマシン定義により、C ++開発者は、これらの高レベルのみの言語の一部が排他的なドメインを持つために使用していた多くの高レベルの抽象化を実現しながら、金属のパフォーマンスと優れた予測可能性(つまり、最小限のランタイムサブシステム)。おそらく、C ++の将来のリビジョンでは、リフレクション機能が選択的に有効になる可能性があります。あるいは、ライブラリがそのようなランタイムサービスを提供する可能性があります(たぶん、現在あるか、最初の1つが後押しですか?)。


別の言語でコンパイルする必要がある言語のランタイムについてのあなたのポイントは、ランタイムがC(Objective-Cのスーパーセット)で書かれているため、Objective-Cの場合には当てはまりません。
リチャードJ.ロスIII

それは違いのない違いです。最終的に、Objective-Cが使用するランタイムサブシステムが実際にはObjective-CではなくCで記述されている場合、どのような違いがありますか?
Mordachai 2013年

3
申し訳ありません; しかし、適切にリンクする限り、CでObjective-Cプログラムをコンパイルできます。実際、私はここでそれを行いました:stackoverflow.com/a/10290255/427309。上記の文全体は誤りです。ランタイムはCを介して完全にアクセス可能であり、その強力な動的言語となっている理由の1つです。
リチャードJ.ロスIII

1
「Cランタイム」は、C標準ライブラリのコードを含む動的ライブラリです。「C ++ランタイム」も同様です。Objective-Cのようなランタイムシステムとはかなり異なります。また、...私はあなたが技術的にはまだObjective-Cのランタイムを使用するだけのCプログラムのCでのObjective-Cランタイムを、使用することができたとしながら-あなたはC.の実際のObjective-Cプログラムをコンパイルすることはできません
celticminstrel

2
C ++ 11にメモリモデルとアトミックがあると、よりポータブルなアセンブラーのようになります。これらは高レベルのものではなく、C ++が以前は移植可能なサポートを欠いていたレベルのものです。しかし、C ++でのUBの量は、何か間違ったことをすると、JavaのようなVMベースの言語や特定のアセンブリ言語とは非常に異なります。たとえば、signed-overflowはC ++ソースでは完全にUBであり、コンパイラーは、たとえばx86向けにコンパイルしても、その事実に基づいて最適化できますが、asmではほとんどすべてのプラットフォームでラップします。最新のC ++は、移植可能なアセンブリ言語とはほど遠いものです。
Peter Cordes

11

C ++に関する設計上の決定を本当に理解したい場合は、EllisとStroustrupによるThe Annotated C ++ Reference Manualのコピーを見つけてください。それは最新の標準では最新ではありませんが、元の標準を通過し、物事がどのように機能するか、頻繁に、どのようにしてそのようになったかを説明します。


6
また、StroustrupによるC ++の設計と進化
James Hopkin

9

それを持っている言語のリフレクションは、リフレクションを有効にするためにコンパイラーがオブジェクトコードに残しておくソースコードの量と、そのリフレクトされた情報を解釈するために利用できる分析機構についてです。コンパイラがすべてのソースコードを保持しない限り、リフレクションはソースコードに関する利用可能な事実を分析する能力に制限されます。

C ++コンパイラーは(RTTIを無視して)何も保持しないため、言語に反映さません。(JavaおよびC#コンパイラは、クラス、メソッド名、および戻り値の型を保持するだけなので、リフレクションデータを少し取得しますが、式やプログラム構造を検査することはできません。つまり、これらの「リフレクション対応」言語でも、あなたが得ることができる情報はかなりまばらであり、その結果、あなたは本当に多くの分析を行うことができません。

しかし、言語の外に出て、完全なリフレクション機能を利用できます。Cでのリフレクションに関する別のスタックオーバーフローの議論への答えは、これについて議論します。


7

リフレクションは以前にc ++で実装できます。

言語によってデフォルトで設定されるべきではない重いコスト(メモリと速度)があるため、ネイティブのC ++機能ではありません。言語は「デフォルトで最大のパフォーマンス」を指向しています。

不要なものにお金を払うべきではなく、あなたが言うには他のアプリケーションよりもエディターで必要とされるため、すべてのコードに「強制」するのではなく、必要な場所にのみ実装する必要があります(エディターや他の同様のアプリケーションで使用するすべてのデータを反映する必要はありません)。


3
また、シンボルを出荷しないのは、顧客/競合他社がコードを確認できるためです。これは、多くの場合悪いことと見なされます。
gbjbaanb 2008

あなたが正しい、私はコード説明問題についてさえもしなかった:)
Klaim

6

C ++がリフレクションを持たない理由は、クラス型が持つメンバー、メンバーに関する情報、関数に関するすべてなど、シンボル情報をオブジェクトファイルに追加する必要があるためです。これにより、宣言によって送信された情報がそれらのオブジェクトファイル(モジュール)から読み取られるため、インクルードファイルは本質的に役に立たなくなります。C ++では、型定義は、それぞれのヘッダーを含めることでプログラム内で複数回発生する可能性があります(これらの定義がすべて同じである場合)。そのため、その型に関する情報をどこに置くかを決める必要があります。ここで合併症。数十のクラステンプレートのインスタンス化を最適化できるC ++コンパイラーによる積極的な最適化も、もう1つの強みです。可能ですが、C ++はCと互換性があるため、


1
コンパイラの積極的な最適化がどのように長所であるか理解できません。詳しく説明できますか?リンカが重複するインライン関数定義を削除できる場合、重複するリフレクション情報の問題は何ですか?デバッガのために、とにかくオブジェクトファイルにシンボル情報が追加されていませんか?
Rob Kennedy

1
問題は、反射情報が無効である可能性があることです。コンパイラがクラス定義の80%を削除する場合、リフレクションメタデータは何を伝えますか?C#とJavaでは、言語はクラスを定義した場合、クラスが定義されたままであることを保証します。C ++により、コンパイラーはそれを最適化します。
2008

1
@Rob、最適化は別のポイントであり、複数のクラスの複雑さに結びついていません。私の意味については、@ jalfのコメント(および彼の回答)を参照してください。
ヨハネスシャウブ-litb 2009

4
Reflect <T>をインスタンス化する場合は、Tの情報を破棄しないでください。これは解決できない問題のようには見えません。
ジョセフガービン

3

C ++でリフレクションを使用するケースはたくさんありますが、テンプレートメタプログラミングのようなコンパイル時の構造を使用して適切に対処することはできません。

N3340は、C ++でリフレクションを導入する方法としてリッチポインターを提案しています。他のものの間で、それはあなたがそれを使用しない限り機能の代金を払わないという問題に対処します。


2

Alistair Cockburn氏によると、反射型の環境ではサブタイピングは保証されません

リフレクションは潜在的なタイピングシステムにより関連します。C ++では、自分が持っている型と、それを使って何ができるかがわかります。


より一般的には、未定義の動作を導入せずに存在しない機能の存在をチェックする機能により、その機能をクラスの新しいバージョンに追加すると、既存のプログラムの明確な動作が変更され、その結果、その機能を追加しても何かが「破壊」されないことを保証できなくなります。
スーパーキャット2013年

2

リフレクションは、プリプロセッサディレクティブのようにオプションにすることができます。何かのようなもの

#pragma enable reflection

そうすれば、このプラグマライブラリがリフレクションなしで作成され(オーバーヘッドは前述のようになりません)、両方の利点を活用できるため、スピードや使いやすさを求める個々の開発者の責任になります。


2

C ++が持つことができる場合:

  • 変数名、変数タイプ、およびconst修飾子のクラスメンバーデータ
  • 関数引数イテレータ(名前ではなく位置のみ)
  • 関数名、戻り値の型、およびconst修飾子のクラスメンバーデータ
  • 親クラスのリスト(定義と同じ順序)
  • テンプレートメンバーと親クラスのデータ。展開されたテンプレート(実際のタイプはリフレクションAPIで使用でき、「そこに到達する方法のテンプレート情報」ではありません)

今日のWebおよびデータベースアプリケーション(すべてのorms、メッセージングメカニズム、xml / jsonパーサー、データのシリアル化など)で普及しているタイプレスデータ処理の核心で非常に使いやすいライブラリを作成するには、これで十分です。

たとえば、Q_PROPERTYマクロ(Qtフレームワークの一部)で サポートされている基本情報http://qt.nokia.com/doc/4.5/properties.htmlは、クラスメソッドとe)をカバーするように拡張されています-C ++とソフトウェアコミュニティ全般。

確かに、私が言及しているリフレクションは、意味の意味や、より複雑な問題(コメントのソースコードの行番号、データフロー分析など)をカバーしていませんが、言語標準の一部である必要はないと思います。


@Vlad:はい、言語へのリフレクションをサポートする機能を追加すると、言語でのリフレクションが得られます。これは、言語委員会が決定した場合にのみ発生する可能性が高く、2011年の時点ではそうなっていないと思います。2020年のADより前に別のC ++標準が出てくるとは思いません。だから、いい考え。それまでの間、上達したい場合は、C ++の外に出る必要があるでしょう。
Ira Baxter


0

C ++での反映、C ++をデータベースアクセス、Webセッション処理/ http、およびGUI開発の言語として使用する場合、私は非常に重要であると考えています。リフレクションの欠如により、ORM(HibernateやLINQなど)、クラスをインスタンス化するXMLパーサー、JSONパーサー、データのシリアル化、およびその他の多くの問題(最初は型のないデータを使用してクラスのインスタンスを作成する必要があります)が妨げられます。

ビルドプロセス中にソフトウェア開発者が利用できるコンパイル時スイッチを使用して、この「使用した分に対して支払う」という懸念を取り除くことができます。

私は、ファームウェア開発者がシリアルポートからデータを読み取るためにリフレクションを必要としません-その場合、スイッチを使用しないでください。しかし、C ++を使い続けたいデータベース開発者として、私はデータメンバーとデータベース構造の間でデータをマップするコードを維持するのが非常に困難で困難な状態に常に移行しています。

Boostシリアライゼーションも他のメカニズムも反射を実際に解決していません-それはコンパイラーによって行われる必要があります-そしてそれが完了すると、C ++は再び学校で学習され、データ処理を扱うソフトウェアで使用されます

私にはこの問題#1(そしてネイティブスレッドプリミティブは問題#2)です。


4
C ++ 、DBアクセス、Webセッションhnadling、またはgui devの言語として使用されると誰が言ったのですか。その種のものに使用するはるかに優れた言語がたくさんあります。また、コンパイル時の切り替えでは問題は解決されません。通常、リフレクションを有効にするか無効にするかの決定は、ファイルごとではありません。個々のタイプで有効にできる場合は機能します。タイプを定義するときに、プログラマーが属性などで指定できる場合、そのリフレクションメタデータを生成するかどうか。しかし、グローバルスイッチ?言語の10%を単純にするために、言語の90%を無効にします。
jalf

次に、クロスプラットフォームでGUIにアクセスできるプログラムが必要な場合、何を使用すればよいですか?柔軟性のないJavaスイング?ウィンドウはC#のみですか?しかし、真実は伝えられるべきであり、実際には、実行可能コードでコンパイルされ、GUIインターフェースとデータベースへのアクセスを提供するプログラムがたくさんあるため、データベースとGUIサポートを使用する必要があります... t QTを使用します。(MT(モンスターツールキット)という名前になっているはずです)
Coyote21

1
@ Coyote21:C#は何年もWindows専用ではありませんでした。(私はMonoのファンではありませんが、ほとんどの場合十分に機能します。)そして、Java用のGUIツールキットはSwingだけではありません。正直なところ、クロスプラットフォームが必要な場合はどちらを選択してもよいでしょう。些細なことをしている場合、C ++はほとんど常にプラットフォーム固有の部分をここまたはそこに配置します。
cHao 2012

ORMにリフレクションが必要な理由はありません。テンプレートを使用すると、これらすべてを実現できます。C ++にORMを提供する一連のフレームワークがあります。
MrFox 2012

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.