簡體   English   中英

使用bind1st和mem_fun引用成員函數

[英]referencing a member function with bind1st and mem_fun

我有一個C ++類,我試圖使用std :: bind1st將成員函數綁定到'this'參數。 例如:

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並使用它。 不幸的是,這不適用於此應用程序。

我該怎么做才能獲得我正在尋找的功能?

謝謝,PaulH


編輯:為了更清楚,我正在尋找一種方法來使一元函數適應你所謂的不帶參數的函數。 我想“綁定” thisMyClass::Bar

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

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

你想用bind1st完成什么?

bind1st函數采用二進制函數,並通過使第一個參數隱式來使其適應一元函數(這可能不是最好的描述,對不起)。 mem_fun的返回值是一元函數。

mem_fun函數返回成員函數的適配器。 改編后的函數不帶任何參數,但返回的適配器接受一個參數,一個指向要使用的MyClass對象的指針。

所以,基本上,你的mem_fun調用返回一個帶有一個參數的適配器,但是bind1st期望一個帶兩個參數的適配器。 有一個mem_fun1返回一個帶有兩個參數的適配器,第一個是對象指針,第二個是函數的參數,但這不是你想要的。

事實上,我不太明白你想要做什么; 為什么普通的mem_fun版本不合適? 如果您需要將對象指針“附加”到適配器,我認為您不能使用當前標准庫執行此操作,除非您使用bind。

當然,您可以創建一個包含對象指針的包裝類,然后只需定義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();

bind1st需要二進制函數,並返回一元函子。 在這里,您傳遞一元函數。

“綁定”的目的是通過將其中一個參數設置為給定值來使用二元函數/仿函數(如具有一個參數的非靜態方法),就像一元參數一樣。

這可行(注意Bar的新原型):

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

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

   void Bar(int i)
   {
   };
};

我想為此添加另一個可能的解決方案,那就是使用C ++ 11中的lambda函數。

這是一個簡單的例子:

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;
}

輸出:“我的名字是以實瑪利。”

我相信它不起作用,因為bind1st()需要二進制函數對象並返回一元函數對象。 由於Bar()不帶參數,因此mem_fun()為您提供了一元函數對象。 bind1st()不知道該怎么做。

你如何打算使用mem_fun()生成的函數對象?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM