2017-09-08 10 views
7

任意のタイプの引数でメソッドを呼び出すことができます。これは、効果的に無関係タイプBarのパラメータでFoo::comp (const Foo& a)を呼び出すこの例(https://ideone.com/RpFRTZmem_funは+ bind2nd

考えます。 だけでなく、私はstd::cout << "a = " << a.s << std::endl;をコメントアウトした場合、私は十分に公正である、それはセグメンテーション違反よりも、値を印刷しない...しかし、なぜそれが最初にコンパイルしない場合、それはまた、何らかの形で動作し、プリントResult: 0

、このコンパイルを行います場所?

#include <functional> 
#include <string> 
#include <iostream> 

struct Foo 
{ 
    bool comp(const Foo& a) 
    { 
     std::cout << "a = " << a.s << std::endl; 
     return a.s == s; 
    } 

    std::string s; 

}; 

struct Bar 
{ 
    int a; 
}; 


template <class F, class T> 
void execute (F f, T a) 
{ 
    std::cout << "Result: " << f (a) << std::endl; 

} 

int main() 
{ 
    Foo* f1 = new Foo; 
    f1->s = "Hello"; 

    Foo f2; 
    f2.s = "Bla"; 

    Bar b; 
    b.a = 100; 

    execute (std::bind2nd (std::mem_fun(&Foo::comp), b), f1); 


    return 0; 
} 
+1

'std :: mem_fun'と' std :: bind2nd'はC++ 11では廃止され、C + 17では廃止されました。 –

+0

また、置換された関数を使用すると、期待される結果(https://ideone.com/9lFJat)とより有用なエラーメッセージが表示されます。 –

+0

@Bob__、はい私はそれを知っています。このバグは、まだC++ 11に移行できないレガシーコードにあります – cppalex

答えて

1

答えはSTDの実装である:: bind2nd:

template<typename _Operation, typename _Tp> 
    inline binder2nd<_Operation> 
    bind2nd(const _Operation& __fn, const _Tp& __x) 
    { 
     typedef typename _Operation::second_argument_type _Arg2_type; 
     return binder2nd<_Operation>(__fn, _Arg2_type(__x)); 
    } 

あなたはそう、右の型に安全ではないCスタイルのキャスト "_Arg2_type(__ xは)" があることがわかりますあなたの例は書かれたかのようにコンパイルされます:

execute (std::bind2nd (std::mem_fun(&Foo::comp), (const Foo&)b), f1); 

これは残念なことに有効なC++コードです。

関連する問題