为什么std::shared_ptr没有operator->*

使用可变参数模板,实现似乎很容易。

有关更多信息,请参见this paper

编辑:这似乎是About shared_ptr and pointer to member operator `->*` and `std::bind`的潜在重复项

最佳答案

这可以在C++ 14之后添加到std::shared_ptr中,而不是您链接的复杂代码中:

template<class Method>
auto operator->*(Method&& method){
  return [t=get(),m=std::forward<Method>(method)](auto&&args){
    return (t->*m)(std::forward<decltype(args)>(args)...);
  };
}

添加SFINAE可选。请注意上述完善的前瞻,这是不完善的。它还支持某种程度上的奇怪“方法”类型,只要它们产生带有operator()的东西就没有其他重要意义。

由于完美转发中的瑕疵,这仍然是不完善的,因此这可能是不理会它而强制使用.get()->*的原因。使用lambda而不是使用class也存在一些小的缺陷,但是这些缺陷可以解决。

克隆接口(interface)的解决方案也存在缺陷(它们可以移动两次而不是一次,或者表示成倍的过载)。

有趣的是,我们可以在不修改->*的情况下注入(inject)上面的std:
namespace notstd{
  template<class...Ts, class Method>
  auto operator->*(std::shared_ptr<Ts...> const& p, Method&& method){
    return [t=p.get(),m=std::forward<Method>(method)](auto&&args){
      return (t->*m)(std::forward<decltype(args)>(args)...);
    };
  }
  template<class...Ts, class Method>
  auto operator->*(std::unique_ptr<Ts...> const& p, Method&& method){
    return [t=p.get(),m=std::forward<Method>(method)](auto&&args){
      return (t->*m)(std::forward<decltype(args)>(args)...);
    };
  }
}

然后using notstd::operator->*将其考虑在内。有趣的是,->*不必是类的非静态成员,就可以像它的许多亲戚(例如->[])那样使用它。

我为unique_ptr包括了一个类似的代码,因为为什么不这样做。

另一种选择是将shared_ptr存储在返回的lambda中:它在看起来像低级操作的过程中增加了开销,因此我没有这样做,并且在unique_ptr上,如果很有趣,则不建议这样做。

现在以上所有内容都很好,但是并不能回答问题。

可以添加一个C++ 03共享的PTR(例如,Boost共享的PTR):
template<class T, class R, class...Args>
struct mem_fun_invoke; // details, exposes `R operator()(Args...)const`
template<class T, class D, class R, class...Args>
mem_fun_invoke<T,R,Args...>
operator->*(std::shared_ptr<Ts...> const& p, R(T::*Method)(Args...)){
  return mem_fun_invoke<T,R,Args...>(p.get(), Method);
}

使用通过宏(如...中)模拟的boost或样板代码复制。这不是完美的方法(每个arg制作两个拷贝而不是一个拷贝?我想我们可以用T args替换T const& args来解决这个问题),但这很难。

相比之下,在C++ 11中很容易。但是std shared ptr是与C++ 11一起设计的,其前身是在之前设计的。因此,对于前体来说,添加->*会带来很多痛苦和样板,几乎没有返回,因此基于这些编写了C++ 11共享ptr。

但是,这部分只是一个观点或一个故事。

关于c++ - 为什么std::shared_ptr没有运算符-> *?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28013423/

10-17 01:40