19

Sergey Ryazanov によると、彼の信じられないほど高速な C++ デリゲートは比較できません。

私の代理人は比較できません。デリゲートにはメソッドへのポインターが含まれていないため、比較演算子は定義されていません。スタブ関数へのポインターは、さまざまなコンパイル単位で異なる場合があります。

読者はどれに答えましたか:

「スタブ関数へのポインターは、さまざまなコンパイル単位で異なる場合があります。」私の知る限り、これは真実ではありません。コンパイラは、異なるコンパイル単位で生成されたテンプレート関数を再利用する必要があります (これは確かですが、Borland はかつてこの規則に違反したと思います)。クラス(「名前のない」名前空間にないクラス)が外部リンケージを使用し、スタブ関数の使用方法が常にインライン化を妨げるためだと思います(ただし、関数のアドレスを取得するため、これは問題にはなりません非インライン バージョンが強制的に生成され、リンカーによって実行される「外部リンケージ」により、類似した名前の関数が 1 つを除いてすべて削除されます (それらは標準によって同一であると想定され、要求されます)...

テンプレート関数を 1 つの翻訳単位 (cpp ファイル) で定義し、同じ関数を別の翻訳単位で別の方法で定義すると、2 つのバージョンのうち 1 つのみが最終的な実行可能ファイルになります。(これは実際には「1 つの定義規則」に違反しますが、少なくとも GCC では動作します... MSVC については不明です。) 要点: [スタブの] アドレスは異なるユニットで同じになります。

これが MSVC に当てはまると思われる場合は、(比較機能を含めて) 記事を更新することをお勧めします。MSVC がこの点で標準の授与である場合。

現在、この記事は 4 年前に作成されており、著者は過去 3 年ほどコメントに返信していないため、上記のコメントにメリットがあるかどうか、およびこの特定の実装を実際に変更できるかどうか疑問に思っています。比較をサポートします。

C++ 標準はそのような使用法を具体的に禁止していますか? もしそうなら、最近のコンパイラは実際にその点で標準に準拠していますか?

4

2 に答える 2

12

コードは標準に準拠しており、問題ありません。彼が ODR に違反している場所は見当たりません。同じテンプレート パラメーターを持つ関数テンプレートのすべてのインスタンス化は、"同じアドレス" を持つ必要があるのは事実です (関数へのポインターはすべて等しい必要があるという意味で)。これが達成されることは重要ではありません。ISO C++03 14.5.5.1[temp.over.link] は、ルールをより詳細に説明しています。

したがって、比較は、準拠した移植可能な方法で定義することができます。

于 2009-10-06T17:28:18.530 に答える