用lambda初始化成员变量

时间:2020-09-17 16:50:39

标签: c++ constructor

假设我有一个模板类:

template<class T>
class Entity
{
public:
  Entity(std::function<void(T*)> init, int idx) : index(idx)
  {
    init(data);
  }

  T* getData(){ return Data; }

private:
  int index;
  T* data;
};

然后我这样创建该类的实例:

Entity<Button> myEnt([](Button* button){
  button = new Button();

  /* some complex, **unique**, initialization of button */

  }, 1);

这将编译,但是当我调用getData()并尝试使用其他函数返回的指针时,程序崩溃。我认为这是因为存在data无法正确初始化的错误,但是我不能说出原因!

如果我将Entity构造函数更改为:

,我可以使程序按需要运行。

Entity(std::function<T*(void)> init, int idx) : index(idx)
{
  data = init();
}

,然后这样称呼它:

Entity<Button> myEnt([](){
  Button* button = new Button();

  /* some complex, **unique**, initialization of button */

  return button;
  }, 1);

但是我认为这是一种不受欢迎的方式,第一种方法应该可以工作,只是缺少了一些东西。

2 个答案:

答案 0 :(得分:2)

您正在按值将data传递给init() ,这意味着lambda正在接收data副本。因此,lambda为其输入参数分配的任何值都将分配给副本,并且不会反映回data

您需要通过引用传递data ,例如:

template<class T>
class Entity
{
public:
  Entity(std::function<void(T*&)> init, int idx) : index(idx)
  {
    init(data);
  }

  T* getData(){ return data; }

private:
  int index;
  T* data;
};
Entity<Button> myEnt([](Button* &button){
  button = new Button();

  /* some complex, **unique**, initialization of button */

  }, 1);

答案 1 :(得分:1)

如果要初始化指针成员,则需要引用或指向成员指针的指针,而不是指针的值。

template<class T>
class entity
{
public:
  Entity(std::function<void(T**)> init, int idx) : index(idx)
  {
    init(&data);
  }

  T* getData(){ return data; }

Private:
  int index;
  T* data;
}

像这样使用它:

Entity<Button> myEnt([](Button** button){
  // you need a pointer to the pointer in order to initialize it
  *button = new Button();

  /* some complex, **unique**, initialization of button */

  }, 1);