Чего мне не хватает для реализации этого делегата?


Просто как государства-вопрос и быть уверенным, я ничего на это не хватает? Что-то важное/очевидно, что я проглядел? Как я могу сохранить любой функтор, указатель на функцию и функцию-член указатель с помощью этого класса делегата (конструктор копирования и оператор присваивания для краткости, как и версий с параметрами).

template<class Type>
void Deleter(void* object){
    Type* obj_ptr = static_cast<Type*>(object);
    delete obj_ptr;
}

template<class Functor>
struct DelegateHelper{
    typedef typename Functor::result_type result_type;

    DelegateHelper(Functor func)
        : func_(func)
    {}

    result_type operator()(){
        return func_();
    }

    Functor func_;
};

template<class Obj, class R>
struct DelegateHelper<R (Obj::*)()>{
    typedef R (Obj::*FuncPtr)();

    DelegateHelper(Obj* obj_ptr, FuncPtr func)
        : object_(obj_ptr)
        , func_(func)
    {}

    R operator()(){
        return (object_->*func_)();
    }

    Obj* object_;
    FuncPtr func_;
};

template<class R>
struct DelegateHelper<R (*)()>{
    typedef R (*FuncPtr)();

    DelegateHelper(FuncPtr func)
        : func_(func)
    {}

    R operator()(){
        return (*func_)();
    }

    FuncPtr func_;
};

template<class Sig>
struct Delegate;

template<class R>
struct Delegate<R ()>{
    typedef R (*SinkPtr)(void*);

    Delegate()
        : object_(0)
        , func_(0)
        , deleter_(0)
    {}

    template<class F>
    Delegate(F func)
        : object_(new DelegateHelper<F>(func))
        , func_(&Sink<DelegateHelper<F> >)
        , deleter_(&Deleter<DelegateHelper<F> >)
    {}

    template<class C, class F>
    Delegate(C* obj, F func)
        : object_(new DelegateHelper<F>(obj, func))
        , func_(&Sink<DelegateHelper<F> >)
        , deleter_(&Deleter<DelegateHelper<F> >)
    {}

    ~Delegate(){
        if(deleter_)
            (*deleter_)(object_);
    }

    R operator()(){
        return (*func_)(object_);
    }

    template<class Type>
    static R Sink(void* obj_ptr){
        Type* object = (Type*)obj_ptr;
        return (*object)();
    }

    typedef void (*DeleteFunc)(void*);

    void* object_;
    SinkPtr func_;
    DeleteFunc deleter_;
};

Для делегата в действие, см. здесь на Ideone.



473
3
задан 22 марта 2011 в 04:03 Источник Поделиться
Комментарии
1 ответ

Вам не хватает const и volatile квалифицированных указатель на метод версии.

Пример:

template<class Obj, class R>
struct DelegateHelper<R (Obj::*)() const>{
typedef R (Obj::*FuncPtr)() const;

DelegateHelper(const Obj* obj_ptr, FuncPtr func)
: object_(obj_ptr)
, func_(func)
{}

R operator()(){
return (object_->*func_)();
}

const Obj* object_;
FuncPtr func_;
};

Кроме того, вы можете (наверное) нужна специализация или внутренние делегаты для обработки функций со значениями возврата Void. Кто-то другой может быть в состоянии заполнить в деталях, но кажется, что некоторые компиляторы все в порядке с

return function_returning_void();

И другие не.

Другое дело, что делает Boost версия и некоторые другие больше быть в состоянии принять и или * аргументы для объекта значение при вызове методов.

2
ответ дан 31 марта 2011 в 04:03 Источник Поделиться