Как вызвать функцию (известную только во время выполнения) со значениями параметров (известными только во время выполнения)? - PullRequest
0 голосов
/ 13 июля 2020

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

Затем функция вызывается каждые несколько секунд.

void Foo::func( std::string s);
void Foo::func( std::string s1 std::string s2, std::string s2);

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

Мне нужно что-то вроде этого:

Один раз проверьте, какую функцию вызывать и установить значение (значения) параметров.

Назначьте инициализированную функцию какой-либо вызываемой переменной.

funcVar = void Foo::func( "blah", "blah", "woof" );

или

funcVar = void Foo::func( "blah" );

Затем вызовите функцию;

for( every few seconds )
{
call FuncVar;
}

Есть ли какая-то вызываемая переменная, которую я могу использовать для этого?

Ответы [ 4 ]

1 голос
/ 13 июля 2020

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

Пример:

struct Foo 
{
    void func( std::string s){ std::cout << "single" << s << std::endl; };
    void func( std::string s1, std::string s2, std::string s3) 
    {   
        std::cout << "tripple " << s1 << " " << s2 << " " << s3 << std::endl;
    }   

    // Select which function to call
    std::function<void()> Select( int what )
    {   
        if ( what == 1 )
        {   
            // Create a callable object and put in also parameters
            return [this]() { func("Hallo"); };
        }
        else
        {   
            // The same for the other selection
            return [this]() { func("This","is","tripple!"); };
        }
    }   
};  

int main()
{   
    Foo foo;
 
    // Pick what you want to select
    auto action = foo.Select( 2 );

    for ( ;; )
    {   
        // and call it as often you like
        action();
    }   
}
0 голосов
/ 14 июля 2020

std :: function должен работать здесь.

std:: function<void()> fun = [&s] () {/* do  work*/};
if (some_condition)
{
   fun = [&s1,&s2,&s3] () {/* do your work*/} ;
}

if(every few seconds)
{
    fun();
}
0 голосов
/ 13 июля 2020

Если вы хотите std :: bind перегружать функции, вы должны указать, какую из них вы хотите использовать:

#include <string>
#include <functional>
#include <iostream>
#include <map>


struct Foo {
    void b() { std::cout << name << ": function 1" << std::endl; }
    void b(int i) {std::cout << name << ": function 2" << std::endl; }

    std::string name;
};


void with_map() {
    Foo f;
    f.name = "with_map";

    std::map<const int, std::function<void()>> map({
        {10, std::bind<void(Foo::*)(), Foo&>(&Foo::b, f)},
        {20, std::bind<void(Foo::*)(int), Foo&, int>(&Foo::b, f, 1)},
    });

    map[20]();
    map[10]();
}


void without_map() {
    Foo f;
    f.name = "without_map";

    std::function<void()> x = std::bind<void(Foo::*)(), Foo&>(&Foo::b, f);
    x();

    x = std::bind<void(Foo::*)(int), Foo&, int>(&Foo::b, f, 1);
    x();
}


int main() {

    without_map();

    with_map();

    return 0;
}

0 голосов
/ 13 июля 2020

Вы можете использовать std::bind для создания функтора с сохраненными аргументами и общим оператором вызова для обоих вариантов использования. Проверьте этот фрагмент:

#include <string>
#include <functional>

struct Foo {
    static void a(std::string) {}
    static void b(std::string, std::string) {}
};

int main() {
    std::function<void()> x;

    if(true) {
        x = std::bind(&Foo::b, "a", "b");
    }

    x();

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