关于shared_ptr和指向成员运算符` - > *`和`std :: bind`的指针 [英] About shared_ptr and pointer to member operator `->*` and `std::bind`

查看:158
本文介绍了关于shared_ptr和指向成员运算符` - > *`和`std :: bind`的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我发现 shared_ptr 没有指向成员运算符 - > * 的指针。我创建了一个简单的例子:

  template< typename Pointer,typename Function,typename ... Args> 
auto invoke1(Pointer p,Function f,Args ... args) - > decltype((p-> * f)(args ...))
{
return(p-> * f)(args ...)
}
struct A {
void g(){std :: cout< A :: g()\\\
; }
};
int main(){
A a;
invoke1(& a,& A :: g); //工作!
std :: shared_ptr< A> sa = std :: make_shared< A>();
invoke1(sa,& A :: g); //编译错误!
}

Q1:为什么shared_ptr没有此运算符?



我为 shared_ptr 添加了此运算符, to work:

  template< typename T,typename Result> 
auto operator - > *(std :: shared_ptr< T>指针,Result(T :: * function)()) - > decltype(std :: bind(function,pointer))
{
return std :: bind(function,pointer);
}
template< typename T,typename Result,typename Arg1>
auto operator - > *(std :: shared_ptr< T> pointer,Result(T :: * function)(Arg1 arg1)) - > decltype(std :: bind placeholder :: _ 1))
{
return std :: bind(function,pointer,std :: placeholders :: _ 1);
}

Q2:这个操作符是否正确?有什么地方任何黄金规则如何实现这样的操作,可能是我重新发明的轮子或走在完全错误的方向,你认为?有一个方法可以有一个单一的函数实现这个运算符,而不是像std ...中的占位符一样多的功能。



结论: std :: bind 可用于我的 invoke 方法。

  template< typename Pointer,typename Function,typename ... Args> 
auto invoke2(Pointer p,function f,Args ... args)
- > decltype(std :: bind(f,p,args ...)())
{
return std :: bind(f,p,args ...)
}

这样,我的示例也可以不需要添加运算符 - > * shared_ptr



std :: bind 现在被视为替换 operator-> * p>

解决方案

在坚果shell中: yes std :: bind是成员函数指针的替换 p>

为什么?因为成员函数指针是可怕的,它们的唯一目的是实现委托,这就是为什么std :: bind和std :: function do



有关如何实现成员函数指针的参考,请参阅我的上一个答案这里。简单来说,成员函数指针被标准削弱,因为它们不允许转换后的调用;这使得它们对于90%的人想从成员函数指针:代表的行为是非常无意义的。



出于这个原因,std :: function用于表示抽象可调用类型,其中std :: bind用于将此绑定到成员函数指针。你绝对不应该使用成员函数指针,而是使用std :: bind和std :: function。


Recently I discovered that shared_ptr does not have pointer to member operator ->*. I created simple example:

template <typename Pointer, typename Function, typename... Args>
auto invoke1(Pointer p, Function f, Args... args) -> decltype((p->*f)(args...))
{
  return (p->*f)(args...);
}
struct A { 
    void g() { std::cout << "A::g()\n"; } 
};
int main() {
  A a;
  invoke1(&a, &A::g); // works!!
  std::shared_ptr<A> sa = std::make_shared<A>();
  invoke1(sa, &A::g); // compile error!!
}

Q1: Why is so? Why shared_ptr does not have this operator?

I added such operator for shared_ptr and the example started to work:

template <typename T, typename Result>
auto operator ->* (std::shared_ptr<T> pointer, Result (T::*function)()) ->decltype(std::bind(function, pointer))
{
    return std::bind(function, pointer);
}
template <typename T, typename Result, typename Arg1>
auto operator ->* (std::shared_ptr<T> pointer, Result (T::*function)(Arg1 arg1)) ->decltype(std::bind(function, pointer, std::placeholders::_1))
{
    return std::bind(function, pointer, std::placeholders::_1);
}

Q2: Is this right implementation for this operator? Are there somewhere any "gold" rules how to implement such operator, probably either I reinvented the wheel or go in completely wrong direction, what do you think? Is there a way to have a single function implementing this operator instead of as many function as there are placeholders in std...

After that I came to conclusion that std::bind can be used in my invoke method.

template <typename Pointer, typename Function, typename... Args>
auto invoke2(Pointer p, Function f, Args... args) 
                     -> decltype(std::bind(f, p, args...)())
{
   return std::bind(f, p, args...)();
}

In this way my example also works without need to add operator ->* to shared_ptr.

Q3: So, is std::bind now considered as a replacement for operator->*?

解决方案

In a nut shell: yes std::bind is a replacement for member function pointers.

Why? because member function pointers are awful, and their only purposes is to implement delegates, which is why std::bind and std::function do

For reference on how member function pointers are implemented, see my previous answer here. In simplest terms, member function pointers are crippled by the standard because they do not allow for calls after casts; this makes them quite pointless for the sort of behavior 90% of people want from member function pointers: delegates.

For this reason, std::function is used to represent an abstract "callable" type, with std::bind being used to bind a this to the member function pointer. You should absolutely not mess with member function pointers, and instead use std::bind and std::function.

这篇关于关于shared_ptr和指向成员运算符` - &gt; *`和`std :: bind`的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆