Вложенные операторы переключения для аргументов шаблонаC++

Программы на C++. Форум разработчиков
Anonymous
Вложенные операторы переключения для аргументов шаблона

Сообщение Anonymous »

У нас есть шаблонная функция, которая принимает 2 аргумента во время компиляции, например

Код: Выделить всё

template
void SomeFunc(double *x, double *y, double *z);
По соображениям производительности лучше иметь специализированные реализации этой функции, основанные на некотором предопределенном наборе значений для a и b. Разумное количество значений для каждого — 10, таким образом, всего возможно максимум 100 реализаций SomeFunc. Если вам интересно, почему, то это потому, что для рассматриваемого приложения знание этих значений во время компиляции позволяет компилятору лучше оптимизировать SomeFunc, особенно потому, что он включает в себя тяжелые плотные вычисления.
Один из способов обойти это — иметь два вложенных оператора переключения и оценивать их во время выполнения каждый раз, когда вызывается функция. Однако это одновременно и избыточно, и приводит к ненужному повторному вычислению одних и тех же операторов переключения каждый раз (поскольку значения a и b не изменяются).
Другой подход может заключаться в использовании указателя на функцию, который предварительно обрабатывает значения a и b и решает, на какую функцию указывать. В данном случае SomeFunc достаточно велик, так что мне не нужно беспокоиться о его встраивании и мне не придется платить здесь за производительность. Тем не менее, проблема в том, что нам придется написать эти два утомительных вложенных оператора переключения, например

Код: Выделить всё

auto DecideFuncPtr(int A, int B)
{
switch(A)
{
case(1): return fa1(B);
case(2): return fa2(B);
...
}
}
каждая специализированная реализация выглядит так:

Код: Выделить всё

// A = 1
auto fa1(int B)
{
switch(B)
{
case(1): return SomeFunc;
case(2): return SomeFunc;
...
}
}

// A = 2
auto fa2(int B)
{
switch(B)
{
case(1): return SomeFunc;
case(2): return SomeFunc;
...
}
}
...
И, наконец, однократная предварительная обработка соответствующей функции (например, в конструкторе):

Код: Выделить всё

auto f = DecideFuncPtr(A, B);

// Use the function later on as such:
f(matrix_A, matrix_B, matrix_C);
Таким образом, вы можете увидеть, насколько неряшливо это может выглядеть с точки зрения дизайна. В частности, если нужно добавить/откорректировать комбинацию реализуемых значений a и b. Есть ли способ сделать это немного лучше, гарантируя при этом, что результирующая функция SomeFunc будет иметь значения a и b, известные во время компиляции?
Для завершения я могу использовать C++17 или даже C++20.

РЕДАКТИРОВАТЬ: Я забыл добавить тип функции (void); это не меняет псевдокод и поставленный вопрос. Также обратите внимание, что значения a и b не обязательно являются последовательными. Здесь я указываю значения 1 и 2 только в демонстрационных целях.

Подробнее здесь: https://stackoverflow.com/questions/787 ... -arguments

Вернуться в «C++»