如何使用已知函数参数避免lambda函数?

时间:2017-07-19 05:49:56

标签: c++ c++11 templates lambda std-function

在下面的代码中,我有一个名为data的变量。它在自身内部保存一个函数,以便稍后调用它们。假设data在另一个库中定义,我无法更改其类型。我为每个成员分配了一个模板函数,其中该函数的一部分是已知的(s3),并且在调用它时必须给出一部分(true)。我不能传递这样的东西:

data[0]=test_func(?,s3);  // error

相反,我必须将lambda函数传递给它:

data[0]=[](bool b){test_func(b,s3);}; // ok

但是lambda函数看起来并不整齐,特别是当我们有100个这样的赋值数组时。有没有办法通过以任何方式更改test_func来避免lambda函数?即使在test_func内使用lambda也没关系,因为它只写了一次。

#include <iostream>
#include <functional>

template<typename F>
void test_func(bool b,F f)
{
    if(b)
        f();
}

void s1()
{
    std::cout<<"s1 \n";
}

void s2()
{
    std::cout<<"s2 \n";
}

void s3()
{
    std::cout<<"s3 \n";
}

int main()
{
    test_func(true,s1);
    test_func(true,s2);
    test_func(false,s1);
    test_func(true,s2);
    /////////////////
    std::function<void(bool)> data[100];
    // data=test_func(?,s3);  // error
    data[0]=[](bool b){test_func(b,s3);}; // ok
    data[0](true);
    return 0;
}

3 个答案:

答案 0 :(得分:2)

如果您想完全避免使用lambda功能,templates可以使用功能(operator()类):

typedef void (&F)(void);
class TestFunc {
    F f;
    public:
    TestFunc(const F f) : f(f) {}
    void operator()(bool B) const { 
        if(B) f(); 
    }
};

使用TestFunc(s3)进行分配。只需typedef F到函数类型,无需模板:

typedef void (&F)(void);

并完全删除模板 - 如果可能的话,我通常更喜欢较少的模板,但那是品味。如果您需要不同的函数签名支持,则只会真正调用模板。

要使用标准库功能,只需更改typedef

typedef std::function<void(void)> F;

答案 1 :(得分:2)

如果每个s_n都是具有相同签名的常规函数​​,则只需从f中删除该test_func参数,然后将该函数本身作为模板参数传递。

template<void(&f)()>
void test_func(bool b)
{
    if(b)
        f();
}

并像这样使用:

data[0] = test_func<s1>;

[temp.param/4]明确允许函数指针和引用作为模板非类型参数:

  

非类型模板参数应具有以下之一   (可选择cv-qualified)类型:

     

[...]

     
      
  • 指向对象或指向函数的指针,
  •   
  • 对对象的左值引用或对函数的左值引用,
  •   

答案 2 :(得分:1)

您可以在辅助函数中创建lambda:

#include <iostream>
#include <string>
#include <functional>
#include <vector>

template<typename F>
void test_func(bool b,F f) {
    if(b) {
       f();
    }
}

std::function<void(bool)> wrap_function(const std::function<void(void)> &f) {
    return [f](bool b){test_func(b,f);};
}

void s1() {
    std::cout<<"s1 \n";
}

int main() {
    std::vector<std::function<void(bool)>> data;

    data.push_back(wrap_function(s1));

    data[0](true);
}

您应该使用std::vectorstd::array或其他标准容器而不是std::function<void(bool)> data[100]