【问题标题】:c++ class using a lambda in constructorc++ 类在构造函数中使用 lambda
【发布时间】:2020-06-30 16:41:17
【问题描述】:

使用 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 来存储 lambda。
  • 你需要template整个类,而不仅仅是构造函数
  • 如果整个类都是模板化的,我将如何使用带有 lambda 的 my_custom_object? random_class::some_function 会是什么样子?
  • 为什么是privatea = a?为什么不this.a = a?或my_custom_object(int a, std::function&lt;int(void)&gt; p) : a(a), p(p) {}

标签: c++ c++11 lambda


【解决方案1】:

您可以采取两种方法。

使用类型擦除的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();
}

【讨论】:

    【解决方案2】:

    如果 lambda 的签名是固定的,您可以删除模板并使用 std::function&lt;ReturnType(parameters)&gt;。你的情况

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

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

    【讨论】:

      猜你喜欢
      • 2017-09-13
      • 2011-12-26
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 2012-09-28
      • 2018-05-25
      相关资源
      最近更新 更多