简体   繁体   English

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

[英]Passing code as an argument (C++)

How would I go about passing a code block to a function in C++. 我如何将代码块传递给C ++中的函数。 In C# I can do something like this: 在C#中,我可以这样做:

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

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

All help and tips are greatly appreciated. 非常感谢所有帮助和提示。

Here is a simple example to get started with... 这是一个简单的例子来开始......

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

and the call would be... 这个电话会......

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

This is very similar to your C# example. 这与您的C#示例非常相似。 And there are better, more versatile ways of doing this as the comments suggest. 正如评论所暗示的那样,有更好,更多样化的方式。 If you had wanted to return a value and take a parameter you could do something like this... 如果您想要返回一个值并获取参数,您可以执行以下操作...

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

This would be similar to the C# version as follows 这与C#版本类似,如下所示

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

C++11 equivalent would be: 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
});

std::function<Result(Param1, Param2, ...)> is a decent default, but you have a few options: std::function<Result(Param1, Param2, ...)>是一个不错的默认值,但你有几个选择:

  1. Declare an auxiliary function and pass a pointer to it. 声明一个辅助函数并传递一个指向它的指针。 This was the only way to go about things in C, and a conventional way to do it in C++98. 这是用C语言进行处理的唯一方法,也是在C ++ 98中实现它的常规方法。

     void example(void (*action)()) { action(); } void example_action() { std::cout << "action\\n"; } example(example_action); 
  2. Accept a function pointer, and pass a lambda that captures no variables. 接受函数指针,并传递一个不捕获任何变量的lambda。 Lambdas are available in C++11 and later. Lambda在C ++ 11及更高版本中可用。

     void example(void (*action)()) { action(); } example([]() { std::cout << "action\\n"; }); 
  3. Accept a callable template type parameter (one with operator() defined), and pass a lambda that may capture variables, or any other callable object (“functor”). 接受可调用的模板类型参数(一个定义了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. Accept a std::function object, and pass a lambda that may capture variables. 接受一个std::function对象,并传递一个可以捕获变量的lambda。

     void example(std::function<void()> action) { action(); } int x = 4; example([x]() { std::cout << "action (" << x << ")\\n"; }); 
  5. Declare an auxiliary function and take pointer to it at compile time. 声明一个辅助函数并在编译时指向它。

     template<void (*action)()> void example() { action(); } example<example_action>(); 

Like any template, #3 will generate a specialisation of example for every action type with which you call it, so it may increase your binary size, but it has no runtime overhead. 与任何模板一样,#3将为您调用它的每个操作类型生成example的特殊化,因此它可能会增加您的二进制大小,但它没有运行时开销。 #4 will allocate space for the closure at runtime, but will only generate one definition of example in the binary. #4将在运行时为闭包分配空间,但只会在二进制文件中生成一个example定义。 #5 is rarer, but it allows the passed-in function to benefit from optimisations such as inlining. #5是罕见的,但它允许传入函数受益于内联等优化。

Use std::function<void()> instead of Action and the C++ syntax for lambda functions: 使用std::function<void()>而不是Action和lambda函数的C ++语法:

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

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

std::function , in comparison to @Les's solution with function pointers, allows you to pass lambdas which capture context and in general any other kind of callable objects. 与带有函数指针的@Les的解决方案相比, std::function允许您传递捕获上下文的lambdas,以及通常任何其他类型的可调用对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM