шаблоны функций - PullRequest
       18

шаблоны функций

2 голосов
/ 27 апреля 2010

Мне сказали создать шаблон функции, который будет принимать 4 аргумента:

  • указатель
  • ссылка
  • указатель на массив
  • указатель на функцию

Как выполнить эту задачу? Я пытался:

#include <iostream>
using namespace std;

int nothing(int a)
{
    return a;
}

template<typename T> T func(int *L, int &M, char *K, int (*P)(int))
{
    cout << L << "," << M << "," << K[0] << "," << P() << endl;
    return 0;    
}

int main()
{
    int x = 3;
    int *z = &x;
    int &y = x;
    char c[3];
    int (*pf)(int) = nothing;

    cout << "some result of func" << func(z, y, c, pf) << endl;

    system("pause");
    return 0;
}

Это дает мне "нет соответствующей функции, я думаю, для 'pf'. Также теперь я не имею никакого контроля над тем, что передавать в pf, или я не прав?

Ответы [ 3 ]

3 голосов
/ 27 апреля 2010

Ты почти у цели. Однако в C ++ ссылка обозначается & (не $), указатель на массив - это указатель на его первый элемент, а указателю на функцию требуются дополнительные скобки: T (*pf)().

Обратите внимание, что он называется шаблоном функции (в отличие от шаблонов классов ).

Редактировать : (Вы не должны редактировать свой вопрос так, чтобы ответы, данные до сих пор, внезапно стали бессмысленными.)

pf(x) вызывает функцию, сохраненную в pf. pf уже является указателем на функцию, поэтому передайте его как есть.
(Кроме того, в вашем объявлении P функция принимает X, а pf принимает int. Я полагаю, это ошибка редактирования?)

Обратите внимание, что с указателями на функции задействованы типы 1..N, один тип результата и 0..N типы аргументов. «Создать шаблон функции, который будет принимать указатель на функцию», может означать любое из этого. Или это означает

template< typename F >
void f(F func);

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

1 голос
/ 27 апреля 2010

Теперь у вас есть некоторые проблемы ...

TYPE (*P)(x) говорит, что вы ожидаете указатель на функцию, которая принимает аргумент типа x - измените его на существующий тип.

В выражении func(z, y, c, pf(x)) вы пытаетесь вызвать указатель на функцию pf вместо того, чтобы просто передать его.

Затем вы вызываете func с параметрами, основанными на разных типах для первых 3 параметров, int и char, но func ожидает, что они основаны на одном типе.
Попробуйте записать, с какими типами будет вызываться func, и попробуйте сопоставить его с сигнатурой для func с заменой TYPE на int.

.

например. если у вас есть следующее:

template<typename T> void f(T* a, T* b);

и попробуйте назвать это так:

int* a = 0;
int* b = 0;
f(a, b);

компилятор создает и вызывает функцию

void f<int>(int*, int*);

Но если вы сделаете следующее:

int*  a = 0;
char* b = 0;
f(a, b);

как называться?

void f<int> (int*,  int* ); // doesn't match, 2nd argument is char*
void f<char>(char*, char*); // doesn't match, 1st argument is int*
1 голос
/ 27 апреля 2010

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

...