4

リフレクションは、他の言語の開発者が c++ に非常に欠けていると感じる機能の 1 つです。特定のアプリケーションについては、その理由がよくわかります。リフレクションがあれば、IDE のオートコンプリートのようなものを書くのはとても簡単です。確かに、シリアライゼーション API があれば、もっと簡単になるでしょう。

一方、C++ の主な信条の 1 つは、使用しないものにはお金を払わないことです。これは完全に理にかなっています。それが私が c++ で気に入っていることです。

しかし、妥協点があるかもしれないと思いました。std::type_infoコンパイラが構造に拡張機能を追加しないのはなぜですか? 実行時のオーバーヘッドはありません。バイナリは最終的に大きくなる可能性がありますが、これは有効/無効にする単純なコンパイラ スイッチである可能性があり、正直なところ、スペースの節約が本当に心配な場合は、とにかく例外と RTTI を無効にする可能性があります。

テンプレートの問題を指摘する人もいますが、コンパイラはstd::type_infoすでにテンプレート型の構造を喜んで生成しています。

-fenable-typeinfo-reflection非常に普及する可能性のある g++ スイッチのようなものを想像できます(そして、boost/Qt/etc のような主流のライブラリは、それを使用するコードを生成するためのチェックを簡単に行うことができます。スイッチ)。このような大規模なポータブル ライブラリは既にコンパイラの拡張機能に依存しているため、これが不合理だとは思いません。

では、なぜこれがより一般的ではないのでしょうか。何かが足りないと思いますが、これに関する技術的な問題は何ですか?

編集:いくつかのメトリックが肥大化の引数を再定義します:

私はかなり大きな Qt プロジェクト (約 45,000 LoC) を見て、メタオブジェクトのサイズを測定しました。Qt moc システムはかなり網羅的なリフレクション システム (型、関数、列挙、メンバー、および "プロパティ" などのいくつかの Qt 固有の概念) であるため、これは妥当なメトリックだと思います。合計 67 個のメタオブジェクトがあったため、些細な量ではありませんが、おかしなことではなく、合計で5479 バイトになりました。ただし、それらのほとんどは 32 バイト以下 (最大は 1427 バイト) でした。最新のコンパイラは、最も単純なプログラムでも 4K 以上のバイナリを生成することを考えると、これらの数値は法外ではありません)。STLこのようなものが に適用されて、それがどのように公平になるかを確認したいと思います。

4

3 に答える 3

1

特定のランタイムリフレクションアプローチを強制する代わりに、必要な情報を生成するために使用できるコンパイル時リフレクション機能が必要です。

そうすれば、実際には使用しない情報にお金を払う必要がなく、メタプログラミングを使用して、追加の事前ビルド手順や複雑な宣言型EDSLを使用せずに、必要に応じてインターフェイスコードを生成できます。

Caspinは、ここで1つの可能なアプローチについて言及しました。正直なところ、この主題がC++に含めるための提案としてプッシュされたことがないように思われることに驚いています。

于 2010-03-18T19:51:51.643 に答える
1

通常、リフレクションの使用は、ソフトウェア設計が不十分であることを示しています。インターフェースとポリモーフィズムを適切に使用するだけで、リフレクションで行うことのほとんどを行うことができます。std::type_info に余分な情報を追加すると、実際にプログラムの肥大化につながります。テンプレートの問題は、それらから std::type_info を生成できないことではなく、型の爆発を取得できるため、テンプレートをインスタンス化するたびに、必要なさらに別の std::type_info オブジェクトが生成されることです。コンパイラスイッチを使用するというあなたの提案は、実際には役に立たないか、意味がありません...まず第一に、標準ではコンパイラスイッチを指定することはありません。これは、実装固有であるためです。リフレクションが無効になっているライブラリからのクラスでリフレクションを使用したい場合はどうなりますか? ほとんどのライブラリがリフレクションを無効にすると (おそらくそうするでしょう)、その機能の有用性が大幅に制限され、ほとんどのライブラリが無効にしない場合は、それを使用せずに料金を支払うことになります。

于 2010-03-18T18:21:39.253 に答える
0

おそらく、C/C++ の型の数が多いと、柔軟なリフレクション プログラミングが難しくなります。任意のプリミティブ型を処理できる架空のデータベースまたはシリアル化インターフェイスには、[unsigned] int、short、[long] long、char、float、[long] double、それらの配列、関連する関数などの特殊なケースが必要です。 name mangler へのインターフェースに。

それが正当な理由だと思うわけではありません。数年前に Boost MPL でリフレクション SQL インターフェースを書きましたが、面倒でした。「ネイティブ」機能を使用すると、はるかに快適で簡単になります。

ほとんどの人は、Apple の Mach Interface Generator や GNU や Microsoft の同様のツールなど、前処理を追加してリフレクションを達成していると思います。

C++ でのサポートの欠如よりも、私にとってもっと驚くべきことは、D や (精神的には) Go など、競争を促進する新進気鋭の言語でのサポートの欠如です。

于 2010-03-18T19:06:39.160 に答える