使用bind1st和mem_fun引用成员函数

发布于 2024-09-12 12:14:45 字数 6166 浏览 2 评论 0原文

我有一个 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 并使用它。不幸的是,这对于该应用程序来说是不可能的。

我可以做什么来获得我正在寻找的功能?

谢谢, 保罗


编辑: 更清楚地说,我正在寻找一种方法来使一元函数适应您所说的不带参数的函数。我想将this“绑定”到MyClass::Bar

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

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

I have a C++ class where I'm trying to use std::bind1st to bind a member function to the 'this' parameter. For example:

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()
   {
   };
};

When I add that last 'bind1st' line, I get the following compiler errors:

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>        ]

I am using STLPort v5.2.1 for a standard library implementation.

Ordinarily, I would switch to boost::bind and use that. Unfortunately, that is not a possibility for this application.

What can I do to get the functionality I'm looking for?

Thanks,
PaulH


Edit:
To be more clear, I'm looking for a way to adapt a unary function to whatever you call a function that takes no parameters. I want to 'bind' this to MyClass::Bar.

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迷乱花海 2024-09-19 12:14:45

您想通过bind1st 实现什么目的?

bind1st 函数采用二元函数,并通过隐式第一个参数将其调整为一元函数(抱歉,这可能不是最好的描述)。 mem_fun 的返回值是一个一元函数。

mem_fun 函数返回成员函数的适配器。适配函数不接受任何参数,但返回的适配器接受一个参数,即指向要使用的 MyClass 对象的指针。

因此,基本上,您的 mem_fun 调用返回一个带有一个参数的适配器,但 bind1st 需要一个带有两个参数的适配器。有一个 mem_fun1 返回一个带有两个参数的适配器,第一个是对象指针,第二个是函数的参数,但这不是您想要的。

事实上,我不太明白你想做什么;为什么普通的 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();

What are you trying to accomplish with bind1st?

The bind1st function takes a binary function and adapts it to a unary function by making the first argument implicit (this may not be the best description, sorry). The return value of mem_fun is a unary function.

The mem_fun function returns an adaptor for a member function. The adapted function doesn't take any arguments, though the adaptor returned takes one argument, a pointer to the MyClass object to be used.

So, basically, your mem_fun call is returning a adaptor that takes one argument, but bind1st is expecting an adaptor that takes two arguments. There is a mem_fun1 which returns an adaptor that takes two arguments, the first being the object pointer and the second being an argument for the function, but that isn't what you want here.

In fact, I don't quite understand what you're trying to do; why is the plain mem_fun version not suitable? If you need the object pointer to be 'attached' to the adaptor, I don't think you can do that with the current standard library, unless you use bind.

Of course, you could make a wrapper class that holds the object pointer, and then just define operator() to call the adaptor with that object.

// 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();
相对绾红妆 2024-09-19 12:14:45

bind1st 需要一个二元函数,并返回一个一元函子。在这里,您传递一个一元函数。

“绑定”的目的是通过将其参数之一设置为给定值来像一元函数/函子一样使用二元函数/函子(如具有一个参数的非静态方法)。

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

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

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

   void Bar(int i)
   {
   };
};

bind1st requires a binary function, and returns an unary functor. Here, you pass an unary function.

The purpose of "binding" is to use a binary function/functor (like a non-static method with one parameter is) like an unary one, by setting one of its parameters to a given value.

This would work (note the new prototype of Bar):

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

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

   void Bar(int i)
   {
   };
};
情绪少女 2024-09-19 12:14:45

我想为此添加另一种可能的解决方案,那就是使用 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;
}

输出:“我的名字是以实玛利。”

I wanted to add one other possible solution to this, and that's using lambda functions from C++11.

Here's a quick example:

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

Output: "My name is Ishmael."

静水深流 2024-09-19 12:14:45

我相信它不起作用,因为 bind1st() 需要一个二进制函数对象并返回一个一元函数对象。由于 Bar() 不接受任何参数,因此 mem_fun() 为您提供一个一元函数对象。 bind1st() 不知道该怎么办。

您实际上打算如何使用 mem_fun() 生成的函数对象?

I believe it's not working because bind1st() requires a binary function object and returns a unary function object. Since Bar() takes no arguments, mem_fun() is giving you a unary function object. bind1st() doesn't know what to do with that.

How do you actually intend to use the function object produced by mem_fun()?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文