Вызов указателя функции шаблона с переменным номером аргумента - PullRequest
10 голосов
/ 07 июля 2011

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

int sum(int a, int b) { return a + b }
int succ(int a)       { return a + 1 }
int size(char* str)   { return strlen(str) }

int call(???) { ??? }

int main() {
  cout << call(sum, 1, 2) << endl;
  cout << call(succ, 41) << endl;
  cout << call(size, "teste") << endl;
}

Ожидаемый результат:

3
42
5

Как мне написать функцию call (при условии, что возвращаемое значение всегда одинаково)?Я могу думать только так:

template<typename T> int call(T func, int a, int b) { return func(a, b) } 
template<typename T> int call(T func, int a)        { return func(a) } 
template<typename T> int call(T func, char* a)      { return func(a) } 

Есть ли способ решить это повторение с помощью шаблонов, va_list или чего-нибудь еще?

Намерение:

Это для рисования геометрических картинок, анализа функции с параметрическим уравнением для рисования.Пример:

Vector2i circle(float t, float radius) {
  return Vector2i(cos(t * 2*PI) * radius, sin(t * 2*PI) * radius);
}
// ...
draw(circle, 10);

Функция circle будет многократно вызываться внутри draw с разными t с (между 0.0 и 1.0).Другие аргументы отрисовки отправляются непосредственно в функции, 10 будет radius.(Vector2i - пользовательский класс).

Ответы [ 3 ]

21 голосов
/ 07 июля 2011

C ++ 0x вариационных шаблонов:

template<typename Func, typename... Args>
auto call(Func func, Args&&... args)
-> typename std::result_of<Func(Args...)>::type
{
    return func(std::forward<Args>(args)...);
}
3 голосов
/ 07 июля 2011

Добавить другую переменную шаблона:

template<typename T, typename U> 
int call(T func, U a) { return func(a) } 

template<typename T, typename U, typename V> 
int call(T func, U a, V b) { return func(a,b) }
2 голосов
/ 08 июля 2011

Как насчет простого #define для текущего решения C ++:

#define call(FUNC, ...) FUNC(__VA_ARGS__)

Вот демо . Я бы посоветовал использовать более подходящее имя, чем общее имя, например call, так как вы используете #define.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...