5

C++0x のいくつかの新機能に少し興味があります。特に、範囲ベースの for ループ初期化リスト。両方の機能が正しく機能するには、ユーザー定義のクラスが必要です。

私はこの投稿に出くわしましたが、トップアンサーは役に立ちました。それが完全に正しいかどうかはわかりません(おそらく完全に誤解しているだけです。最初の回答の3番目のコメントを参照してください)。初期化子リストの現在の仕様によると、ヘッダーは 1 つの型を定義します。

template<class E> class initializer_list {
public:
    initializer_list();

    size_t size() const; // number of elements
    const E* begin() const; // first element
    const E* end() const; // one past the last element
};

これは仕様で確認できます。 Ctrl + F 'class initializer_list'だけです。

= {1,2,3}をクラスに暗黙的にキャストするためinitializer_listに、コンパイラは と の間の関係について何らかの知識を持っている必要が{}ありinitializer_listます。何かを受け取るコンストラクターはないため、initializer_list は、コンパイラーが実際に生成しているものにバインドされるラッパーです。

これはループと同じでfor( : )、ユーザー定義型が機能する必要があります (ただし、仕様によると、配列と初期化子リストのコードを必要としないように更新されています。しかし、初期化子リストには が必要な<initializer_list>ので、ユーザー定義コードの要件です。プロキシー)。

ここでこれがどのように機能するかを完全に誤解していますか? これらの新機能がユーザー コードに非常に大きく依存していると考えるのは間違いではありません。機能が中途半端で、機能全体をコンパイラに組み込むのではなく、コンパイラによって半分が行われ、インクルードで半分が行われているように感じます。これの理由は何ですか?

編集:「ユーザーコードに大きく依存する」ではなく、「コンパイラコードに大きく依存する」と入力しました。これは私の質問を完全に放棄したと思います。私が混乱しているのは、コンパイラに組み込まれている新機能に関するものではなく、ユーザー コードに依存するコンパイラに組み込まれているものです。

4

2 に答える 2

3

これらの新機能はコンパイラ コードに非常に大きく依存していると考えるのは間違いではありません。

彼らはコンパイラに大きく依存しています。ヘッダーを含める必要があるかどうかに関係なく、どちらの場合も、現在のコンパイラでは構文が解析エラーになります。for (:)は、今日の標準に完全には適合しません。許可されている唯一の構文はfor(;;)

機能が中途半端で、機能全体をコンパイラーに組み込むのではなく、半分をコンパイラーが行い、半分をインクルードで行っているように感じます。これの理由は何ですか?

サポートはコンパイラーに実装する必要がありますが、システムのヘッダーを組み込む必要があります。これはいくつかの目的に役立ちます。初期化リストの場合は、型 (コンパイラ サポートへのインターフェイス) をユーザーのスコープに持ち込んで、それを使用する方法を用意できるようにします (va_args が C でどのように機能するかを考えてください)。範囲ベースの for (これは単なるシンタックス シュガーです) の場合、コンパイラがその魔法を実行できるように、Range をスコープに入れる必要があります。for ( for-range-declaration : expression ) statement標準では([6.5.4]/1 ドラフト) と同等に定義されていることに注意してください。

{ 
   auto && __range = ( expression ); 
   for ( auto __begin = std::Range<_RangeT>::begin(__range), 
         __end = std::Range<_RangeT>::end(__range); 
         __begin != __end; 
         ++__begin ) { 
      for-range-declaration = *__begin; 
      statement 
   } 
} 

概念なしで (C++0x の意味ではなく) 実装できる配列と STL コンテナーでのみ使用しRangeたいが、構文をユーザー定義クラス (独自のコンテナー) に拡張したい場合、コンパイラーは次のことができます。既存のRangeテンプレートに簡単に依存します (独自の可能な専門化を使用)。定義されているテンプレートに依存するメカニズムは、コンテナーに静的インターフェースを要求することと同じです。

他のほとんどの言語は、通常のインターフェース (コンテナーなど) を必要とし、その上でランタイム ポリモーフィズムを使用する方向に進んでいます。これを C++ で行う場合、STL コンテナーは共通のベースまたはインターフェイスを共有せず、ポリモーフィックに使用する準備ができていないため、STL 全体を大幅にリファクタリングする必要があります。

あるとしても、現在の標準は、それが出るまでに弱体化することはありません。

于 2009-12-07T07:46:55.400 に答える
1

それは単なる構文糖です。コンパイラは、指定された構文構造を、標準型/シンボル名を直接参照する同等の C++ 式に展開します。

これは、最新の C++ コンパイラがその言語と「外の世界」の間に持つ唯一の強力な結合ではありません。たとえば、extern "C"C のリンク モデルに対応するためのちょっとした言語ハックです。スレッド ローカル ストレージを宣言する言語指向の方法は、動作する多くの RTL ハッカーに暗黙的に依存しています。

または C を見てください。 経由で渡された引数にどのようにアクセスします...か? 標準ライブラリに依存する必要があります。しかし、それは C コンパイラがスタック フレームをどのように正確にレイアウトするかに非常に強く依存する魔法を使用します。

アップデート:

どちらかといえば、ここで C++ が採用したアプローチは、言語に焼き付けられた固有のコレクションまたは範囲型を追加するという代替手段よりも C++ の精神に近いものです。代わりに、ベンダー定義の範囲型を介して行われています。ベンダー定義のアクセサ マクロがなければ同様に役に立たない可変引数とそれほど違いはないと思います。

于 2009-12-07T03:32:13.240 に答える