将mem_fun_ref与代理对象一起使用

Using mem_fun_ref with a proxy object

本文关键字:对象 一起 代理 mem fun ref      更新时间:2023-10-16

我正在尝试使用std::mem_fun_ref(是的,不推荐使用版本原因如下)通过代理调用成员函数。

template<typename T>
struct proxy {
  T& operator*() { return *t; }
  T* operator->() { return t; }
  // no address of etc
  T* t;
};
struct A {void foo() {}};
int main()
{
  A a;
  proxy<A> pa = {&a};
  std::mem_fun_ref_t<void, A>
    fn = std::mem_fun_ref(&A::foo);
  fn(pa); // borks
  return 0;
}

这适用于C++11std::mem_fn,但不适用于boost::mem_fn,但是我不能使用这两者,因为我需要指定粘合剂在另一个地方,得到的粘合剂的类型是未指定用于boost::mem_fn。如果我能的话,这不会是个问题使用decltype,但我不能,因为代码需要与兼容C++03.

解决这个问题最简单的方法是什么?一种习俗mem_fun_through_proxy

编辑:另一个注意事项是不能更改proxy类。

按照Georg的建议,我实现了自己的解决方案。这是简短的版本:

// snipped solution: does not include const version and hack for void
// returns
#include <functional>
namespace mine {
template<typename Ret, typename T>
class mem_fun_ref_t : public std::unary_function<T, Ret>
{
public:
  explicit
  mem_fun_ref_t(Ret (T::*f)())
  : f(f) { }
  template<typename U>
  Ret
  operator()(U& u) const
  { return (*u.*f)(); }
  Ret
  operator()(T& t) const
  { return (t.*f)(); }
private:
  Ret (T::*f)();
};
} // mine
template<typename T>
struct proxy {
  T& operator*() { return *t; }
  T* operator->() { return t; }
  // no address of etc
  T* t;
};
struct X {
  int foo() {return 23;}
};
int main()
{
  mine::mem_fun_ref_t<int, X> fn(&X::foo);
  X x;
  // normal
  fn(x);
  proxy<X> px = {&x};
  fn(px);
  return 0;
}