2009-03-05 2 views
2

Это кажется непоследовательным. Почему мы используем & Пример :: func вместо примера :: func? есть ли применение для примера :: func или & exampleFunction? это не похоже, что мы можем сделать ссылку на функцию, чтобы исключить Example :: func. и я не могу думать о способе использования & exampleFunction, так как exampleFunction уже возвращает указатель.есть использование для & func или class :: func в C++?

#include <iostream> 
class Example { 
public: 
    void func() { std::cout <<"print me\n"; } 
}; 
void exampleFunction() { std::cout << "print me too\n"; } 
typedef void (Example::*ExampleFunc_t)(); 
typedef void (*ExampleFunction_t)(); 
int main() 
{ 
    Example e; 
    ExampleFunc_t  f = &Example::func; 
    ExampleFunction_t f2 = exampleFunction; 
    (e.*f)(); 
    f2(); 
    return 0; 
} 

ответ

6

Так как стандарт определяет указатели на функции.

Вы всегда должны использовать оператор адреса &, чтобы получить указатель на функцию, но для регулярных функций и статической функции-члена в стандарте определено неявное преобразование из функции в указатель-к-функции.

Это не определено для (не статической) функции-члена, потому что вы не можете получить lvalue для нестационарной функции-члена.

От стандарта C++:

4,3 Функция к указателю преобразования

  1. Именующее выражение типа функции Т может быть преобразован в RValue из типа «указатель на T. «Результат - указатель на функцию.

с сноской 52:

Это преобразование не относится к не-статическим функциям-членов, так как именующему, который относится к не-статической функции-члена не может быть получена.

Я думаю, что они бы скорее разрешить только & функцию, по соображениям совместимости, но о том, что неявное преобразование является просто артефактом C наследия ...

+0

В C++ есть также функционирует референции (ЬурейиЕ void (& FuncRef_t)()), но не ссылки на функции-члены. – dalle

+0

Да, я думаю, что полезно использовать это неявное преобразование для функций. потому что чаще всего вы хотите передать указатель в любом случае (вы не можете «передать функцию», поэтому он передает указатель на него неявным преобразованием). Я думаю, причина T :: f не достаточна, потому что это было бы неоднозначно: если бы это было –

+0

указатель на функцию-член, то вы не можете записать Base :: f(); для вызова функции базового класса. вам нужно будет написать (this -> * Base :: f)(); который вроде бы сосет. Так что наличие & T :: foo для получения указателя - хорошее решение, я думаю. –

1

Точка использования Function Pointers. Для очень грубый пример, предположим, что у вас есть класс, имеющий несколько переменных-членов, по которым вам может понадобиться для сортировки элементов массива этого типа класса, как это:

struct CL { 
    int x, y, z; 
}; 

bool sort_by_x(const CL& obj1, const CL& obj2); 
bool sort_by_y(const CL& obj1, const CL& obj2); 
bool sort_by_z(const CL& obj1, const CL& obj2); 

... 

CL obj[100]; 
... 
sort(obj, obj+100, sort_by_x); 
... 
sort(obj, obj+100, sort_by_y); 
... 
sort(obj, obj+100, sort_by_z); 

Здесь станд сортировки используется :: для сортировки массива объектов CL. Посмотрите на третий параметр, это имя функции. Функция std :: sort может принимать указатель на функцию в третьем параметре и использовать эту функцию в качестве компаратора для сортировки массива. Нам нужно определить функции sort_by_ *, чтобы std :: sort работал как ожидалось.

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