2012-05-21 2 views
6

У меня есть функция, которая требует указателя на функцию в качестве аргумента:C++ функция привязки для использования в качестве аргумента другой функции

int func(int a, int (*b)(int, int)) 
{ 
    return b(a,1); 
} 

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

int c(int, int, int) 
{ 
    // ... 
} 

Как я могу связать первый аргумент c так, что я могу сделать:

int i = func(10, c_bound); 

Я смотрю на std::bind1st, но я не могу понять это. Он не возвращает правильность указателя функции? У меня есть полная свобода адаптации func, поэтому возможны любые изменения подхода. Althoug Я хотел бы, чтобы пользователь моего кода смог определить свои собственные c ...

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

Проект, к сожалению, требует C++98.

ответ

12

Вы не можете этого сделать. Вам нужно будет изменить func, чтобы сначала взять объект функции. Что-то вроде:

int func(int a, std::function< int(int, int) > b) 
{ 
    return b(a, rand()); 
} 

В самом деле, нет никакой необходимости b быть std::function, это может быть шаблонных вместо:

template< typename T > 
int func(int a, T b) 
{ 
    return b(a, rand()); 
} 

, но я бы придерживаться версии std::function для ясности и несколько меньше выведенный из строя компилятор на ошибках.

Тогда вы могли бы сделать что-то вроде:

int i = func(10, std::bind(&c, _1, _2, some-value)); 

Примечание все это C++, но вы можете сделать это в C++ 03 с помощью Boost.

+2

даже если Мне нужен код C++ 98, этот ответ был легко преобразован в его эквивалент повышения. – romeovs

1

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

int c_bound(int a, int b) { 
    return c(a,b,some_value); 
} 

Это, очевидно, не является универсальным решением, но может решить текущую проблему. В противном случае решение K-ballo кажется единственным простым общим. Однако для этого требуется, чтобы вы могли изменить подпись func. Если у вас действительно есть API, который вы не можете дотронуться до подписи, и вам все равно нужно привязать аргумент И если вышеупомянутое решение не решит ваш конкретный случай: (осторожно, излишнее) Я всегда хотел использовать LLVM решение для компиляции функции во время выполнения и передачи ее адреса в таких ситуациях.

0

Вам не удастся использовать функцию аргумента 3 как функцию аргумента 2; В основном потому, что нет реального способа определить, что будет делать третий параметр.

Хотя выше ответ будет работать, вот еще один вариант:

Если один из параметров c(), используемых в func, является постоянным, вы могли бы написать функцию-обертку для c(int, int, int):

int d(int a, int b) 
{ 
    return c(a, b, 0); //use a constant parameter 
} 

или, если вы можете определить, 3-й параметр из двух заданных параметров, вы можете также попробовать:

int e(int a, int b) 
{ 
    int extra = 0; 
    ///Determine extra from a, and b 
    return c(a, b, c); 
} 
Смежные вопросы