2013-12-18 2 views
2

У меня есть функтор, как этотРазыменование указатель на функтор внутри разыменованного класса

struct foo 
{ 
    int a; 
    foo(a) : a(a) {} 
    int operator()(int b) { return a+b; } 
}; 

и класс, как этот

class bar 
{   
    public: 
    foo* my_ftor; 
    bar(foo* my_ftor) : my_ftor(my_ftor) {} 
    ~bar() {} 
}; 

Теперь предположим, указатель на этот класс, который содержит указатель на обув ,

foo MyFoo(20); 
bar MyBar(&MyFoo); 

В функции передаю ссылку на бар, и я хочу запустить функтор. У меня это работает следующим образом:

void AnyFunction(bar* RefToBar) 
{ 
    int y; 
    y = RefToBar->my_ftor->operator()(25); 
} 

Есть ли какой-либо другой «очистительный» способ разыменовать функтор? Что-то похожее на

y = RefToBar->my_ftor(25); 

не будет работать, к сожалению ...

Любая идея? Спасибо

+2

(* RefToBar-> my_ftor) (25) –

+0

Вы также можете создать класс смарт-указатель на функтор, который сам по себе функтор и просто называет 'оператор()' из направленный объект. С C++ 11 можно сделать полностью общий шаблон. –

+0

bar * не является ссылкой – zoska

ответ

2

Используйте реальные ссылок:

class bar { 
public: 
    foo &my_ftor; 

    bar (foo &f) : my_ftor(f) {} 
}; 


void AnyFunction (bar &reftobar) { 
    int y = reftobar.my_ftor(25); 
} 

И позвоните, как этот

foo myFoo(20); 
bar myBar (myFoo); 

AnyFunction (myBar); 

В интересах полноты, вот еще один ответ, который является более современным подходом.

class foo { 
public: 
    foo (int i) : a(i) {} 

    int operator() (int x) const { 
     return x + a; 
    } 
private: 
    int a; 
}; 

template <typename F> 
void AnyFunction (const F &func) { 
    int y = func(25); 
} 

Таким образом, вы можете перейти в foo непосредственно:

AnyFunction (foo (20)); 

Или другой вид объекта функции, как лямбда:

AnyFunction([](int x) -> int { 
    return x + 20; 
}); 

Вы также могли бы расширить bar включить следующие функции:

int run_foo (int x) const { 
    return my_ftor (x); 
} 

и связать его (#include <functional>):

AnyFunction (std::bind (&bar::run_foo, &myBar, std::placeholders::_1)); 
+0

Я предполагаю, что мои обычаи C не позволяют мне использовать & на C++, должны иметь глубокий взгляд на него. Хороший. – Manex

+1

Как и указатель, убедитесь, что 'myFoo' не выходит из области действия до того, как вы закончите с' myBar'. – Anthony

0
y = (*RefToBar->my_ftor)(25); 

(лучше использовать станд :: функции и не нарушают Деметра)

1

Использование std::function они предназначены для хранения функтор любого рода.

#include <functional> 
#include <iostream> 

struct foo 
{ 
    int _a; 
    foo(int a) : _a(a) {} 
    int operator()(int b) { return _a+b; } 
}; 


class bar 
{   
public: 
    std::function<int (int)> _ftor; 

    bar(std::function<int (int)> my_ftor) : _ftor(my_ftor) {} 
    ~bar() {} 
}; 

void AnyFunction(bar& RefToBar) 
{ 
    int y = RefToBar._ftor(25); 
    std::cout << "Y: " << y << std::endl; 
} 

int AnotherFunction(int b) 
{ 
    return b + 11; 
} 

int main(int argc, char const *argv[]) 
{ 
    foo MyFoo(20); 
    bar MyBar(MyFoo); 
    bar MyBar_2(AnotherFunction); 
    bar MyBar_3([](int b) { return b + 56; }); 


    AnyFunction(MyBar); 
    AnyFunction(MyBar_2); 
    AnyFunction(MyBar_3); 
    return 0; 
} 

http://ideone.com/K3QRRV

Смежные вопросы