Использование mem_fun_ref с прокси-объектом - PullRequest
0 голосов
/ 29 марта 2012

Я пытаюсь использовать 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 ++ 11 std::mem_fn но не boost::mem_fn, но я не могу использовать ни один из них, поскольку мне нужно указать тип связующего в другом месте, а тип полученного связующего не указан для boost::mem_fn.Это не было бы проблемой, если бы я мог использовать decltype, но я не могу, поскольку код должен быть совместим с C ++ 03.

Какой самый простой способ обойти это?Пользовательский mem_fun_through_proxy?

Редактировать: Еще одна оговорка: нельзя изменить класс proxy.

1 Ответ

0 голосов
/ 19 апреля 2012

Как рекомендовал Георг, я реализовал собственное решение.Вот короткая версия:

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