c++ class using a lambda in constructor

ugl*_*bob 1 c++ lambda c++11

Using c++11 I want to create a class that uses a lambda as part of a calculation.

//contrived sample of potential usage
void random_class::some_function(void)
{
 auto an_object = new my_custom_object(5, [this](){ return random_class_member * 5; });
 an_object.do_some_processing();
 random_class_member++;
 an_object.do_some_processing();
}
Run Code Online (Sandbox Code Playgroud)

I am not quite sure how to go about declaring and defining my_custom_object.

class my_custom_object
{
public:
 template <typename Proc>
 my_custom_object(int a, Proc p)
 {
  privatea = a;
  privatep = p;
 }
 void do_some_processing()
 {
  privatea += privatep();
 }
private:
 int privatea;
 Proc privatep;
}
Run Code Online (Sandbox Code Playgroud)

unknown type name 'Proc'

Mil*_*nek 5

您可以采取两种方法。

使用类型擦除 std::function

例如:

class my_custom_object {
public:
    my_custom_object(int a, std::function<void()> p)
    {
        privatea = a;
        privatep = p;
    }
    void do_some_processing()
    {
        privatea += privatep();
    }

private:
    int privatea;
    std::function<void()> privatep;
};
Run Code Online (Sandbox Code Playgroud)

这允许my_custom_object接受任何不接受参数的类似函数的东西。但是有一些性能开销,因为privatep必须在运行时解析调用。这可能可以忽略不计,但如果这是在程序的性能关键部分的紧密循环中发生的,则可能很重要。

呼叫站点看起来与您现在拥有的完全一样:

void random_class::some_function(void)
{
   my_custom_object an_object{5, [this](){ return random_class_member * 5; }};
   an_object.do_some_processing();
   random_class_member++;
   an_object.do_some_processing();
}
Run Code Online (Sandbox Code Playgroud)

my_custom_object它拥有的功能类型的模板。

例如:

template <typename Proc>
class my_custom_object {
public:
    my_custom_object(int a, Proc p)
    {
        privatea = a;
        privatep = p;
    }
    void do_some_processing()
    {
        privatea += privatep();
    }

private:
    int privatea;
    Proc privatep;
};
Run Code Online (Sandbox Code Playgroud)

这将允许privatep在编译时静态解析您的调用,这可能比使用std::function. 这确实意味着Proc现在的类型是my_custom_object虽然类型的一部分,因此在某些情况下它不太灵活。

由于 C++17 添加了类模板参数推导,调用站点看起来完全相同:

void random_class::some_function(void)
{
   my_custom_object an_object{5, [this](){ return random_class_member * 5; }};
   an_object.do_some_processing();
   random_class_member++;
   an_object.do_some_processing();
}
Run Code Online (Sandbox Code Playgroud)

如果必须使用 C++17 之前的编译器,则必须my_custom_object明确指定模板参数:

void random_class::some_function(void)
{
   auto func = [this](){ return random_class_member * 5; };
   my_custom_object<decltype(func)> an_object{5, func};
   an_object.do_some_processing();
   random_class_member++;
   an_object.do_some_processing();
}
Run Code Online (Sandbox Code Playgroud)