2013-10-09 5 views
3

У меня возникла интересная идея создания типа векторной таблицы с использованием функторов. Однако после дальнейшего анализа казалось бы, что это было бы мечтой из-за того, что это было бы непомерно дорогостоящим, поскольку всю таблицу нужно было бы сгенерировать, чтобы передать некоторые из параметров функции из функции, которая вызывает функтор. Функтор в этом случае будет действовать как прокси-сервер для управления разностями параметров между функциями, которые вызывает функтор.Можно ли отложить генерацию функтора?

Confused еще? :-) Пример:

#include <functional> 

class classA {}; 
void fn1(int a); 
void fn2(classA& a); 

void fn_x(int fn_to_call, int a1, classA& a2) { 
    std::function<void()> vtable[] = { 
    [&]{ fn1(a1); }, 
    [&]{ fn2(a2); } 
    }; 
    vtable[fn_to_call](); 
} 

void fn_y(int fn_to_call, int a1, classA& a2) { 
    switch(fn_to_call) { 
    case 0: 
     return fn1(a1); 
    case 1: 
     return fn2(a2); 
    } 
} 

Для краткости я пропустил чеки, когда я делаю это по телефону.

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

Когда количество функций для отправки невелико, это не большая проблема, но по мере увеличения числа он становится все хуже и хуже.

Если бы я мог как-то отложить создание объектов-функторов до тех пор, пока он не будет вызван, это было бы оптимальным. Это возможно?

Редактировать также, как будет обрабатывать компилятор? Будет ли результатом несколько записей стека вызовов (вызов функтора, а затем вызов целевой функции), или это будет так же эффективно, как и переключатель?

+0

где определен 'function'? – Oswald

+1

@ Освальд: Я бы поставил на 'std'. –

+0

@Adrian: Если они были простыми указателями на функции, массив может быть статическим (обратите внимание, что лямбда, которая не фиксирует ничего, конвертируется в обычный указатель функции соответствующего типа). Чем это будет просто записано в исполняемый файл компилятором без каких-либо затрат времени на выполнение. –

ответ

2

Чтобы принять и обобщить некоторые рекомендации в комментариях, почему бы не создать только один набор функторов, который знает, как пересылать аргументы?

#include <functional> 

class classA {}; 
void fn1(int a) {} 
void fn2(classA& a) {} 

void fn_x(int fn_to_call, int a1, classA& a2) { 
    using namespace std::placeholders; 
    static std::function<void(int, classA&)> vtable[] = { 
    std::bind(&fn1, _1), 
    std::bind(&fn2, _2), 
    }; 
    vtable[fn_to_call](a1, a2); 
} 

int main() 
{ 
    classA a; 
    fn_x(0, 3, a); 
    fn_x(1, 3, a); 
    return 0; 
} 
+0

Как будет обрабатывать компилятор? Будет ли результатом несколько записей стека вызовов (вызов функтора, а затем вызов целевой функции), или это будет так же эффективно, как и переключатель? – Adrian

+0

Это полностью зависит от компилятора. Вы должны попробовать и посмотреть. –

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