【问题标题】:Put functions into vector and execute将函数放入向量并执行
【发布时间】:2014-10-26 23:49:26
【问题描述】:

我想将向量/双端队列作为函数容器。

此容器必须采用具有不同参数的不同函数。

示例函数:

program_data::getInstance().function(int,std::string);
program_data::getInstance().foo(int);
program_data::getInstance().exam(int,std::string,double);

您能否展示示例代码如何放置这些带有参数的函数到 std::vector / std::deque 和 execute

我认为我应该使用 std::function 和 std::bind 但我不知道如何支持具有不同 args 大小的不同函数。

带参数 -> 我的函数(称为function foo exam,来自program_data)使用参数执行一些操作。

例如:通常我执行这个函数:

program_data::getInstance().function(10,"halo");

现在我想将这些函数放入std::vector // deque 并使用我放入函数的参数执行。即(如果我将上面的函数放入向量并使用(伪代码)vector[0].run();,那么我的程序运行函数program_data::getInstance().function(int,std::string);

【问题讨论】:

  • "with arguments" - 意思是你想创建一些东西,当被调用时,它与使用指定参数调用函数具有相同的效果?
  • 您可能正在寻找 lambda 表达式? stackoverflow.com/questions/7627098/…
  • 您的参数值在入队时是否已知?您的函数的返回类型是否始终相同?
  • 对不起,'enque' 是什么意思? - 是的,返回类型相同 -> void
  • 如果std::vector/std::deque可以在编译时填写,你可以简单地制作一个包含函数的结构体。

标签: c++ c++11 vector


【解决方案1】:

当然,使用std::vector<std::function<void()>> - 即类型擦除的函数容器的向量,它可以容纳任何可不带参数调用的对象:

std::vector<std::function<void()>> vector;

// populate the vector
vector.push_back([]{ program_data::getInstance().function(10,"halo"); });

// execute items in the vector
vector[0]();

在这里,我使用无捕获 lambda 填充向量;您还可以将 lambdas 与捕获、绑定表达式 (std::bind) 和其他可调用对象一起使用。

如果将 lambda 与捕获一起使用,则需要确保捕获的变量要么按值捕获,要么具有包含可调用集合的生命周期:

std::string tmp;
vector.push_back([&tmp]{ program_data::getInstance().something(tmp); });

【讨论】:

  • 您能否举例说明变量是通过引用发送的? std::string tmp; program_data::getInstance().function(10,tmp); 其中 tmp 是 std::string &amp;tmp; 的参数当然当变量可以访问时
【解决方案2】:

我建议使用std::functionlambda expressions

std::vector<std::function<void()>> functions;
functions.push_back([](){ program_data::getInstance().function(123, 456, "str"); });

这会在您的向量“函数”中添加一个函数。通过调用functions[0](),这将调用 lambda 表达式,然后使用 123、456 和“str”作为参数调用您的函数。

【讨论】:

    【解决方案3】:

    您可以使用std::function/std::bind。因此,首先您需要确定从调用方传递给这些函数的内容,即确定函数签名。原理与虚函数相同。因此,例如,您想传递一个序列号(调用函数的顺序)并且什么都不返回:

    #include <vector>
    #include <functional>
    
    typedef std::function< void( int ) > Function;
    typedef std::vector<Function> Functions;
    
    
    void func1( int seq, const std::string &str );
    void func2( const std::string &str );
    void func3( int seq );
    
    void run()
    {
        Functions functions;
        // populate functions
        functions.push_back( std::bind( func1, std::placeholders::_1, "foobar" ) );
        functions.push_back( std::bind( func2, "foobar too" ) );
        functions.push_back( func3 ); // you can use std::bind here as well, just to show it can be omitted if function signature matches
    
        // call them
        for( size_t i = 0; i < functions.size(); ++i ) {
            functions[i]( i );
        }
    }
    

    这种方法的好处,可以用于pre c++11的带有boost的编译器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      相关资源
      最近更新 更多