2012-02-08 9 views
4

in another message of mineと記載されているように、"<"(より小さい)でメンバー関数の2つのポインタを比較することはできません。少なくとも、これは未定義の動作を引き起こします。私は両方のVisual C++だけでなく、GCCと、このコードをコンパイルするために管理しているstd :: set内の関数とメソッドポインタ

私の知る限り
template <class Receiver, class Param = void*, class Return = void> 
class EventReceiver : public IFunction<> { 

protected: 

    std::set< Return(Receiver::*)(Param) > test; 
    std::set< Return(*)(Param) > test2; 
... 

、STDを作るために::マップまたはSTD ::何も設定し、それができなければなりませんセットの値を "<"と比較してください。これは、上記のコンテナまたは実際のコンパイラが、ポインタとメソッドの比較方法を実際に実装していることを意味しますか?

+0

私の答えは間違っていました - ポインタとメンバとポインタは同じではありません。謝罪いたします! – templatetypedef

+0

@templatetypedef FWIW C++ 11の対応する言葉は、§20.8.5/8の下にあります。これは困惑している。私はいくつかの(コンパイルビル)の友人をここに招待しました – sehe

+0

@Xeo [チャット](http://chat.stackoverflow.com/transcript/message/2582471#2582471)のアイデアを与えている – sehe

答えて

0

実際には、という例題のコードがコンパイルされたと誤解を招くです。真実は、セットがを使用できないことです。データを挿入しようとすると、予想されるエラーが発生します。

これは、C++テンプレート関数の「暗い面」です。それらはあなたがそれらを使うまで存在しません(そしてあなたがするまでコンパイルエラーを生成しません)。

チェックこのアウト:)(タイプ「無効(X :: * constの)の

無効なオペランド:

#include <set> 

class X {}; 

int main() { 

    typedef void(X::*FuncPtr)(); 
    std::set<FuncPtr> set; 
    std::less<FuncPtr> less; 
    FuncPtr f1; 
    FuncPtr f2; 
    //set.insert(f1); // both of these lines 
    //less(f1,f2);  // produce an error 
}; 

最後の2行のいずれかのコメントを削除するには、エラーを生成しますオペレータ< 'バイナリへの ''と' のボイド(X :: * のconst)()'

Compile it online yourself here

0

std::set<T>は、より小さい演算子を直接使用する代わりに、std::less<T>を使用します。 Tがポインタ型である場合、より小さい演算子がそうでない場合でも、std::less<T>は合計順序であることが保証されます。

編集:C++ 98標準の20.3.3項には、関数へのポインタは含まれていますが、メンバへのポインタは含まれていない、「ポインタ型」と書かれています。

+1

に興味がありません。 "組み込み演算子が<, >,<=, > =でない場合でも、ポインタ型の特殊化は合計注文をもたらします。" - 今質問は、 "メンバーへのポインタ"型も "ポインタ型"ですか?標準は、他の質問を参照して、いいえと言うようです。 – Xeo

+0

あなたはそうです。私は私の答えを修正しました。 –

+1

まあ、std :: lessもうまくいきません! [std :: less ()。演算子()(関数、other-> function))]はコンパイルされません:エラーC2296: '<':不正な、タイプ 'void(__thiscall Fair :: PtrIcon :: * const)(Fair :: Pointer *)' !!! –

関連する問題