2012-03-29 1 views
0

Я пытаюсь использовать std::mem_fun_ref (Да, устаревшая версия . Причины ниже), чтобы вызвать функцию-член через прокси-сервер.Использование 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; 
} 

Это хорошо работает с 11 C++ std::mem_fn, но не boost::mem_fn, но я могу использовать ни один из них, как мне нужно указать тип связующего вещества в другое место и тип полученного связующего is не указан для boost::mem_fn. Это не было бы проблемой, если бы я мог использовать decltype, но я не могу, так как код должен быть совместим с C++ 03.

Что является самым простым способом обойти это? Таможня mem_fun_through_proxy?

Редактировать: Еще одно предостережение в том, что класс proxy не может быть изменен.

+0

Что делать, если вы добавляете 'operator T &() {return * t}' в свой прокси-сервер? –

+0

@ KerrekSB А, я забыл. Изменение прокси также невозможно. Фактически, это итератор. – pmr

+0

Почему не 'fn (* pa)'? –

ответ

0

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

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