2010-04-06 4 views
19

Я хочу спросить о указателе в C++++ указатель на функцию C, Beginner Вопрос

У меня есть простой код:

int add(int a, int b){ 
return a+b; 
} 

int runner(int x,int y, int (*functocall)(int, int)){ 
return (*functocall)(x,y); 
} 

Теперь предположим, что я называю эти функции, используя этот путь:

cout<<runner(2,5,&add); 

или, может быть

cout<<runner(2,5,add); 

есть ли разница? потому что, когда я пытался, результат тот же и без ошибок.

Большое спасибо

ответ

0

Я считаю, что второй вызов автоматически разрешает к первому вызову в компиляторе ...

+0

Итак, вы имеете в виду, что второй звонок является правильным? – BobAlmond

+1

Нет, я имею в виду, что компилятор разрешает либо вызов указателю на функцию, и это действительно вопрос синтаксического предпочтения. –

10

Функция будет неявно приведен к указателю согласно C++ Standard (4,3/1). Нет никакой разницы. Однако это преобразование никогда не применяется к нестатической функции-члену. Для них вы должны явно написать &.

3

Нет никакой разницы. Для согласованности с другими способами получения указателя вы можете использовать &, но само название не имеет другого смысла, поэтому предполагается, что он означает «получить адрес».

Это очень похоже на имена переменных массива, которые выступают в качестве адреса первого элемента массива.

0

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

+0

Есть объекты, называемые функциями (в терминах выражений): 'add' - такой объект, его тип -' int (int, int) '. Однако они неявно распадаются на указатели на себя во многих контекстах. – avakar

+0

, пожалуйста, покажите пример, где функция и указатель на функцию как выражение, действительно отличаются – Andrey

+0

Да, функции не являются объектами, но они являются функциями (сюрприз xD). Например, 'void f() {} void (& fr)() = f;' работает, потому что f является выражением типа функции, и вы привязываете ссылку к нему, тогда как 'void (& fr)() = & f;' does not потому что '& f' является выражением типа указателя. Другой пример - попробуйте сделать 'sizeof (f)' и заметьте, что он терпит неудачу, потому что функции не имеют размера. Как говорит @avakar, тип f здесь - 'void()', а один из add - 'int (int, int)' –

3

Нет, в этом конкретном случае нет разницы. Любой из них дает вам адрес функции.

Обратите внимание, что в C++ для получения указателя на элемент требуется, чтобы вы использовали оператор '&'.

1

Обратите внимание, что вы можете иметь ссылки на функцию

int runner(int x,int y, int (&functocall)(int, int)){ 
return functocall(x,y); 
} 

Теперь призывающей его с &add больше не будет работать, потому что вы пытаетесь связать ссылку на функцию к указателю, а не к функции. Иногда это просвечивает при использовании шаблонов

template<typename T> 
int runner(int x,int y, T &functocall, T otherfunc){ 
return functocall(x,y) + otherfunc(y, x); 
} 

Теперь называя его runner(10, 20, add, add) потерпит неудачу, потому что T Стараются быть выведено как указатель функции и типа функции (без распада до указателя делаются при переходе к ссылке параметр!).