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

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

问题描述:

我该如何去将代码块传递给C++中的函数。在C#中,我可以做这样的事情:传递代码作为参数(C++)

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

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

所有帮助和提示是极大的赞赏。

+6

google'std :: function'和'C++ lambda' –

+1

函数指针非常方便... – owacoder

+1

函数对象也很有用。在互联网上搜索'operator()'。 –

这里上手...

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); 

如下

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

接受函数指针是非常有限的,这意味着您可以只传递非线性函数,捕获lambdas或纯函数指针(=>没有绑定的方法调用,只是为了举例)。您应该接受一个'std :: function'。 –

使用std::function<void()>而不是Action这将是类似于C#版本和C++的lambda函数语法:

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

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

std::function,相较于与函数指针@莱斯的解决方案,可以让你通过捕捉上下文和一般其他类型的可调用对象的lambdas。

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, ...)>是一个体面的默认,但你有几种选择:

  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是可捕捉的变量,或任何其他可调用对象(“仿函数”)。

    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对象,并传入可捕捉变量的λ。

    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>(); 
    

任何模板,#3将产生example为与你怎么称呼它,所以它可能会增加你的二进制文件的大小每一个动作类型的特,但它没有运行时开销。#4将在运行时为闭包分配空间,但只会在二进制中生成一个example的定义。 #5比较少见,但它允许传入的函数受益于内联等优化。