在构造函数中使用 lambda 的 C++ 类

c++ class using a lambda in constructor

本文关键字:C++ lambda 构造函数      更新时间:2023-10-16

Using c++11 我想创建一个使用 lambda 作为计算一部分的类。

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

我不太确定如何声明和定义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;
}

未知类型名称"Proc">

您可以采取两种方法。

使用文字擦除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;
};

这允许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();
}

模板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;
};

这将允许您在编译时静态解析对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();
}

如果必须使用 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();
}

如果 lambda 的签名是固定的,您可以删除模板并使用std::function<ReturnType(parameters)>。在您的情况下

using Proc = std::function<int(void)>;

应该工作。然后,您可以传递一个不带参数并返回 int 的 lambda。