10

std::bind1st を使用してメンバー関数を「this」パラメーターにバインドしようとしている C++ クラスがあります。例えば:

class MyClass
{
public:
   void Foo()
   {
       using namespace std;

       // this works fine
       this->Bar();

       // this also works fine
       mem_fun( &MyClass::Bar )( this );

       // this does not
       bind1st( mem_fun( &MyClass::Bar ), this )();

       // this is not a possibility for this program
       boost::bind( &MyClass::Bar, this )();
   };

   void Bar()
   {
   };
};

最後の「bind1st」行を追加すると、次のコンパイラ エラーが発生します。

1>stl/_function.h(189) : error C2039: 'second_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1>        with
1>        [
1>            _Ret=void,
1>            _Tp=MyClass
1>        ]
1>        .\MyClass.cpp(50) : see reference to class template instantiation 'stlp_std::binder1st<_Operation>' being compiled
1>        with
1>        [
1>            _Operation=stlp_std::mem_fun_t<void,MyClass>
1>        ]
1>stl/_function.h(189) : error C2146: syntax error : missing ',' before identifier 'second_argument_type'
1>stl/_function.h(189) : error C2065: 'second_argument_type' : undeclared identifier
1>stl/_function.h(190) : error C2955: 'stlp_std::unary_function' : use of class template requires template argument list
1>        stl/_function_base.h(40) : see declaration of 'stlp_std::unary_function'
1>stl/_function.h(191) : error C2039: 'second_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1>        with
1>        [
1>            _Ret=void,
1>            _Tp=MyClass
1>        ]
1>stl/_function.h(191) : error C2146: syntax error : missing ',' before identifier 'second_argument_type'
1>stl/_function.h(191) : error C2065: 'second_argument_type' : undeclared identifier
1>stl/_function.h(194) : error C2955: 'stlp_std::unary_function' : use of class template requires template argument list
1>        stl/_function_base.h(40) : see declaration of 'stlp_std::unary_function'
1>stl/_function.h(195) : error C2955: 'stlp_std::unary_function' : use of class template requires template argument list
1>        stl/_function_base.h(40) : see declaration of 'stlp_std::unary_function'
1>stl/_function.h(197) : error C2146: syntax error : missing ';' before identifier '_ArgParamType'
1>stl/_function.h(197) : error C3254: 'stlp_std::binder1st<_Operation>' : class contains explicit override 'param_type' but does not derive from an interface that contains the function declaration
1>        with
1>        [
1>            _Operation=stlp_std::mem_fun_t<void,MyClass>
1>        ]
1>stl/_function.h(197) : error C2838: 'param_type' : illegal qualified name in member declaration
1>stl/_function.h(197) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(197) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(198) : error C2146: syntax error : missing ';' before identifier '_ConstArgParamType'
1>stl/_function.h(198) : error C3254: 'stlp_std::binder1st<_Operation>' : class contains explicit override 'const_param_type' but does not derive from an interface that contains the function declaration
1>        with
1>        [
1>            _Operation=stlp_std::mem_fun_t<void,MyClass>
1>        ]
1>stl/_function.h(198) : error C2838: 'const_param_type' : illegal qualified name in member declaration
1>stl/_function.h(198) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(198) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(199) : error C2039: 'first_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1>        with
1>        [
1>            _Ret=void,
1>            _Tp=MyClass
1>        ]
1>stl/_function.h(199) : error C2146: syntax error : missing ',' before identifier 'first_argument_type'
1>stl/_function.h(199) : error C2065: 'first_argument_type' : undeclared identifier
1>stl/_function.h(199) : error C2955: 'stlp_std::__call_traits' : use of class template requires template argument list
1>        stl/type_traits.h(452) : see declaration of 'stlp_std::__call_traits'
1>stl/_function.h(203) : error C2039: 'first_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1>        with
1>        [
1>            _Ret=void,
1>            _Tp=MyClass
1>        ]
1>stl/_function.h(203) : error C2146: syntax error : missing ';' before identifier '_M_value'
1>stl/_function.h(203) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(203) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(208) : error C2061: syntax error : identifier '_ConstArgParamType'
1>stl/_function.h(211) : error C2061: syntax error : identifier '_ArgParamType'
1>stl/_function.h(212) : error C2535: '_Result stlp_std::binder1st<_Operation>::operator ()(void) const' : member function already defined or declared
1>        with
1>        [
1>            _Operation=stlp_std::mem_fun_t<void,MyClass>
1>        ]
1>        stl/_function.h(208) : see declaration of 'stlp_std::binder1st<_Operation>::operator ()'
1>        with
1>        [
1>            _Operation=stlp_std::mem_fun_t<void,MyClass>
1>        ]

標準ライブラリの実装に STLPort v5.2.1 を使用しています。

通常は、boost::bind に切り替えて使用します。残念ながら、それはこのアプリケーションでは可能ではありません。

探している機能を取得するにはどうすればよいですか?

ありがとう、ポールH


編集:より明確にするために、単項関数を、パラメーターを取らない関数と呼ぶものに適応させる方法を探しています。に「バインド」thisしたいMyClass::Bar

class SomeOtherClass
{
public:
    template< typename Fcn >
    void ExecuteFcn( Fcn fcn )
    {
        fcn();
    };
};

some_other_class.ExecuteFcn( bind1st( mem_fun( &MyClass::Bar ), this );
4

4 に答える 4

5

bind1st で何を達成しようとしていますか?

このbind1st関数は二項関数を取り、最初の引数を暗黙的にすることでそれを単項関数に適応させます (これは最適な説明ではないかもしれません、申し訳ありません)。の戻り値mem_funは単項関数です。

このmem_fun関数は、メンバー関数のアダプターを返します。適応された関数は引数を取りませんが、返されたアダプターは 1 つの引数 (使用される MyClass オブジェクトへのポインター) を取ります。

したがって、基本的に、mem_fun呼び出しは 1 つの引数を取るアダプターを返しますがbind1st、2 つの引数を取るアダプターを期待しています。最初の引数はmem_fun1オブジェクト ポインターで、2 番目の引数は関数の引数ですが、ここで必要なのはそれではありません。

実際、私はあなたが何をしようとしているのかよくわかりません。プレーンmem_funバージョンが適していないのはなぜですか? オブジェクト ポインターをアダプターに「アタッチ」する必要がある場合は、バインドを使用しない限り、現在の標準ライブラリでそれを行うことはできないと思います。

もちろん、オブジェクト ポインターを保持するラッパー クラスを作成し、operator() を定義して、そのオブジェクトでアダプターを呼び出すこともできます。

// Quick and dirty example of this.
// You could extend this with a second template parameter for return type, if
// needed. Just be sure to specialize for void if you do that.
template<typename Object>
struct bound_mem_fun_t { 
    bound_mem_fun_t(mem_fun_t<void, Object> f, Object* o) : fun(f), obj(o) { } 
    void operator()() { fun(obj); } 
    mem_fun_t<void, Object> fun; 
    Object* obj; 
};

MyClass a;
bound_mem_fun_t<MyClass> func(mem_fun(&MyClass::Bar), &a);
func();
于 2010-08-03T19:15:10.787 に答える
4

bind1st二項関数を必要とし、単項ファンクタを返します。ここでは、単項関数を渡します。

「バインディング」の目的は、パラメーターの 1 つを特定の値に設定することにより、バイナリ関数/ファンクター (1 つのパラメーターを持つ非静的メソッドのようなもの) を単項関数のように使用することです。

これは機能します ( の新しいプロトタイプに注意してくださいBar):

class MyClass
{
public:
   void Foo()
   {
       using namespace std;

       // this works fine
       bind1st( mem_fun( &MyClass::Bar ), this )(42);
   };

   void Bar(int i)
   {
   };
};
于 2010-08-03T19:16:41.013 に答える
1

これに別の可能な解決策を追加したかったのですが、それはC++ 11のラムダ関数を使用しています。

簡単な例を次に示します。

class MyClass
{
    std::string mName;

public:
   MyClass(const char* name) : mName(name) {};

   void Foo()
   {
       std::cout << "My name is " << mName << std::endl;
   };
};

void CallMyFn(std::function<void()> fn)
{
    fn();
}

int main()
{
    MyClass myInstance("Ishmael");

    CallMyFn( [&]() { myInstance.Foo(); } );

    return 0;
}

出力: 「私の名前はイシュマエルです。」

于 2013-09-04T13:09:46.870 に答える
0

bind1st()二項関数オブジェクトを必要とし、単項関数オブジェクトを返すため、機能していないと思います。Bar()引数を取らないためmem_fun()、単項関数オブジェクトが提供されます。 bind1st()それをどうするかわかりません。

によって生成された関数オブジェクトを実際にどのように使用するつもりmem_fun()ですか?

于 2010-08-03T19:08:28.617 に答える