将代码作为参数传递(C ++)

时间:2015-10-14 22:51:24

标签: c++

我如何将代码块传递给C ++中的函数。在C#中,我可以这样做:

void Example(Action action)
{
    action();
}

Example(() => {
    //do something
});

非常感谢所有帮助和提示。

4 个答案:

答案 0 :(得分:4)

以下是一个简单的示例...

void Example(void (*x)(void))
{
    x();
}

并且电话会是......

Example([] { cout << "do something\n"; });

这与您的C#示例非常相似。正如评论所暗示的那样,有更好,更多样化的方式。如果你想要返回一个值并采用参数,你可以做这样的事情......

int Example2(int (*y)(int i), int p)
{
    return y(p);
}
// ...
auto ret = Example2([](int p) -> int { cout << p << "\n"; return p; }, 2);

这与C#版本类似如下

int Example2(Func<int,int> y, int p)
{
    return y(p);
}
// ...
var ret = Example2((p) => { /*etc*/ return p; }, 2);

答案 1 :(得分:3)

C ++ 11等效于:

void Example(const std::function<void()>& action)
{
    // always good to make sure that action has a valid target
    if(action != nullptr)
        action();
}

Example([] {
    //do something
});

答案 2 :(得分:3)

std::function<Result(Param1, Param2, ...)>是一个不错的默认值,但您有几个选择:

  1. 声明一个辅助函数并传递一个指向它的指针。这是用C语言进行处理的唯一方法,也是用C ++ 98实现它的传统方法。

    void example(void (*action)()) {
        action();
    }
    
    void example_action() {
        std::cout << "action\n";
    }
    
    example(example_action);
    
  2. 接受函数指针,并传递一个不捕获任何变量的lambda。 Lambda在C ++ 11及更高版本中可用。

    void example(void (*action)()) {
        action();
    }
    
    example([]() {
        std::cout << "action\n";
    });
    
  3. 接受可调用的模板类型参数(定义了operator()的参数),并传递可捕获变量的lambda或任何其他可调用对象(“functor”)。

    template<class F>
    void example(F action) {
        action();
    }
    
    int x = 4;
    example([x]() {
        std::cout << "action (" << x << ")\n";
    });
    
    struct example_action {
        void operator()() {
            std::cout << "action\n";
        }
    };
    
    example(example_action());
    
  4. 接受std::function对象,并传递可捕获变量的lambda。

    void example(std::function<void()> action) {
        action();
    }
    
    int x = 4;
    example([x]() {
        std::cout << "action (" << x << ")\n";
    });
    
  5. 声明一个辅助函数,并在编译时指向它。

    template<void (*action)()>
    void example() {
        action();
    }
    
    example<example_action>();
    
  6. 与任何模板一样,#3将为您调用它的每个操作类型生成example的特化,因此它可能会增加您的二进制大小,但它没有运行时开销。 #4将在运行时为闭包分配空间,但只会在二进制文件中生成example的一个定义。 #5很少见,但它允许传入函数受益于内联等优化。

答案 3 :(得分:1)

使用std::function<void()>代替Action和lambda函数的C ++语法:

void Example(std::function<void()> action)
{
    action();
}

Example([]() {
    //do something
});
与@ Les的函数指针解决方案相比,

std::function允许您传递捕获上下文的lambdas,以及通常任何其他类型的可调用对象。