2015-04-26 3 views
0

Я передаю указатель на функцию-член в функцию шаблона. Что-то вроде этого,Вызов указателя на функцию-член, переданную в функцию

Foo bar; /* bar.baz(...) is a function */ 
    auto pnt = bar.baz; 

    passMmbFunc<...,decltype(pnt)>(...,pnt); 

Соответствующие части passMmbFunc выглядят так,

template <..., typename D> 
    void map(..., D func) { 
    ... 
    auto ret = func(someVal); 
    ... 
    } 

Я предположил, что синтаксис вызова указатель на функцию-член такой же, как обычный указатель на функцию, но это не. Я получаю следующее сообщение об ошибке,

error: must use '.*' or '->*' to call pointer-to-member function in 'func (...)', e.g. '(... ->* func) (...)' 

passMmbFunc Изнутри, как бы я называю ПНТ? Я знаю, что указатель на функцию-член можно вызывать, если у вас есть объект соответствующего класса. Но поскольку я передаю его как параметр, это не так. Итак, есть ли способ вызвать указатель на функцию-член, если у вас есть только указатель и нет объекта?

+0

Вы сделали неправильное предположение. – dtech

+0

Синтаксис отключает вас, потому что (как предполагал предыдущий комментарий) вы слишком много думали. Вы не можете вызвать указатель на нестационарную функцию-член без объекта, и синтаксис гарантирует это. – PaulMcKenzie

+0

Что бы вызвать функцию-член как 'size()' или 'to_string()' или любое среднее значение без экземпляра соответствующего класса? – Mat

ответ

1

Функция-указатель на элемент должна быть вызвана на объект - она ​​не может работать как отдельная функция. Отсюда и ваша ошибка. baz должна быть вызвана с некоторыми Foo используя либо синтаксис .* или ->*:

auto ptr_to_mem = &Foo::baz; 
Foo f, *pf; 

ptr_to_mem();  // error 
(f.*ptr_to_mem)(); // ok 
(pf->*ptr_to_mem()); // ok 

Способ сделать это в C++ является связывают указатель на член с объектом, который вы будете называть его. Стандарт даже предоставляет функцию, чтобы сделать это: std::bind:

auto pnt = std::bind(&Foo::baz, bar); 
pnt(); // this is the equivalent of bar.baz(); 

Одним из возможных источников путаницы в том, что auto pnt = bar.baz; будет на самом деле делать то, что вы хотите в Python. Просто не в C++.

+0

Вы имеете в виду 'способ сделать это в C++ (11)' – texasbruce

+0

Я бы сказал, что к настоящему времени C++ 11 является старым и поддерживается достаточно, чтобы считаться неявным. – dtech

+0

Я не думаю, что C++ 11 «неявно» разрешен большинством компиляторов, поскольку вам всегда нужно передавать 'std = C++ 11' – texasbruce