Dynami c Функция в Cpp - PullRequest
       9

Dynami c Функция в Cpp

1 голос
/ 18 апреля 2020

Я работал над проектом cpp и хотел бы динамически выполнять свою функцию. У меня есть функция, у которой есть 9 вариантов при запуске.

Пусть заглавная буква будет условием булевого типа, а строчная буква - функцией. И давайте предположим, что моя функция имеет свои условия (AI) вне функции в качестве глобальной области видимости. И условия не будут изменены во время выполнения. Он будет установлен только один раз перед запуском этой функции и не будет изменен во время этой функции.

void Myfunction(){
if(A) a(); // I would not use else if or switch since I should check all conditions.
if(B) b();
...
if(I) i();
return;
}

И функция будет вызываться с бесконечной петлей

int main(void){
//Conditions A - I is declared here
while (1) Myfunction;
return 0;
}

Я знаю, что использование оператора if довольно медленное, а также проверка не-переменных условий - это чушь. Чтобы сэкономить вычислительные ресурсы и сэкономить время при выполнении этой функции, я хотел бы выполнить свою функцию динамически. Это означает, что если сначала проверить свои условия (AI), то функция решает, какое выражение использовать.

Например, если у нас есть условия A, B, C как истинные и все другие (D - I) как ложный. Я хотел бы, чтобы функция автоматически стала.

void Myfunction(){
a();
b();
c();
return;
}

Я искал inte rnet, но не смог найти ни одной. Я нашел несколько статей о шаблонах в cpp, но это был не тот случай, который я искал.

Спасибо, что прочитали эту статью. Поскольку я совсем новичок в Stackoverflow, возможно, я допустил некоторые ошибки в этом посте. Если в этом посте есть что-то, что противоречит правилам Stackoverflow, пожалуйста, дайте мне знать. Я был бы более чем рад изменить мой пост.

Спасибо.

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Я пытался создать решение, используя шаблоны функций.

Две основные функции: GetMyFunction() и MyFunctionTemplate().

MyFunctionTemplate() - это шаблон функции, который будет принимать все ожидаемые параметры в качестве аргументов шаблона bool (нетипизированные аргументы шаблона).

GetMyFunction() функция будет возвращать указатель на требуемую специализацию MyFunctionTemplate() во время выполнения.

GetMyFunction() также делает еще одну вещь, он должен проверить все комбинации параметров и вернуть соответствующую функцию.

Эта специализация MyFunctionTemplate() будет создана во время компиляции, и я считаю, что эти if ( ) проверки в пределах MyFunctionTemplate() будут удалены, поскольку это константы времени компиляции (Кто-то, пожалуйста, подтвердите это).

#include <iostream>

using namespace std;

void aFunc() { cout << "in a()" << endl; }
void bFunc() { cout << "in b()" << endl; }
void cFunc() { cout << "in c()" << endl; }
void dFunc() { cout << "in d()" << endl; }

template <bool a, bool b, bool c, bool d>
void MyFunctionTemplate()
{
    if (a) aFunc();
    if (b) bFunc();
    if (c) cFunc();
    if (d) dFunc();
}

void (*GetMyFunction(bool a, bool b, bool c, bool d))()
{
    if (a && b && c && d)
        return &MyFunctionTemplate<true, true, true, true>;
    if (a && b && c && !d)
        return &MyFunctionTemplate<true, true, true, false>;
    // And all other combinations follows....
}

int main(void)
{
    // Conditions A - I is declared here
    bool a = true, b = true, c = true, d = true;
    // auto MyFunction = GetMyFunction(a, b, c, d);
    void (*MyFunction)(void) = GetMyFunction(a, b, c, d);
    MyFunction();

    return 0;
}
0 голосов
/ 19 апреля 2020

Итак, я нашел решение для моего проекта, используя указатели функций. Сначала я сделал свои функции как, а затем сохранил эти указатели функций в массиве указателей на функции. Сохраняя эти указатели функций в массив указателей функций, я подсчитал, сколько элементов будет сохранено в моем массиве указателей функций. Таким образом, используя эти подсчитанные значения, я могу перебирать каждый элемент моего массива функций. На самом деле все мои функции были в классе. так что мои функции были на самом деле функциями-членами.

Чтобы использовать указатели на функции-члены, мне нужно было создать структурный тип указателя на функцию. А также объявите новую переменную-указатель функции в моем классе с именем CC, чтобы использовать ее во всей области видимости своего класса.

typedef void(CC::FunctionPointers)();
FunctionPointers* FunctionPointerArray;
FunctionPointerArray = (FunctionPointers*)malloc(sizeof(FunctionPointers) * 4); // I will just say 4 conditions right ere. 
// Malloc-ing the FunctionPointers type can be possible, or there is another option 
// like making direct array (Both two are the same in terms of operation)

И затем у меня есть объявление и определение функции в моем классе с именем CC.

void aFunc() { cout << "in a()" << endl; }
void bFunc() { cout << "in b()" << endl; }
void cFunc() { cout << "in c()" << endl; }
void dFunc() { cout << "in d()" << endl; }

Затем я делаю функцию-член массива указателей на функцию-указатель. И давайте сохраним это возвращаемое значение как totalIterCounts

int GenerateFunctionPointers(void){
    if(a) FunctionPointerArray[0] = &CC::aFunc();
    if(b) FunctionPointerArray[1] = &CC::bFunc();
    if(c) FunctionPointerArray[2] = &CC::cFunc();
    if(d) FunctionPointerArray[3] = &CC::dFunc();
    return a + b + c + d; // To set exact iteration counts;
}

Тогда Когда мне нужно будет вызвать мои функции, я сделаю это l oop для вызова моих функций.

void callFunctions(){
for (int i = 0 ; i < totalIterCounts ; i++){
    (this->*FunctionPointerArray[i])();
}

Таким образом, в целом весь мой класс будет выглядеть примерно так:

class CC{
Public:
    typedef void(CC::FunctionPointers)();
    FunctionPointers* FunctionPointerArray = NULL;
    // I do know that using non-variable in malloc is kind of meaningless.
    int totalIterCounts; // To count how many iterations I need.

    CC(){
        totalIterCounts = GenerateFunctionPointers();
    }

    void aFunc() { cout << "in a()" << endl; }
    void bFunc() { cout << "in b()" << endl; }
    void cFunc() { cout << "in c()" << endl; }
    void dFunc() { cout << "in d()" << endl; }

    int GenerateFunctionPointers(void){
        FunctionPointerArray = (FunctionPointers*)malloc(sizeof(FunctionPointers) * 4) 
        //I have not initialized every element here, Assigning NULL would be safer.
        if(a) FunctionPointerArray[0] = &CC::aFunc();
        if(b) FunctionPointerArray[1] = &CC::bFunc();
        if(c) FunctionPointerArray[2] = &CC::cFunc();
        if(d) FunctionPointerArray[3] = &CC::dFunc();
        return a + b + c + d; // To set exact iteration counts;
    }

    void CallFunctions(){
        for (int i = 0 ; i < totalIterCounts ; i++){
        (this->*FunctionPointerArray[i])();
    }
}

И функция CallFunctions() может быть вызвана извне в будущем. Это решение сработало для меня прошлой ночью. Отдельное спасибо всем, кто помог мне с этим вопросом!

Я впервые отвечаю на свой вопрос в Stackoverflow, поэтому у меня могут возникнуть некоторые проблемы с этим ответом. Пожалуйста, дайте мне знать, если я должен изменить или отредактировать что-то. Еще раз большое спасибо.

...