Что происходит, когда присваивается тип, содержащий лямбда-выражение?

Допустим, у меня есть какой-то тип, завершающий функцию, может быть, лямбда-функция:

template<typename Function>
  struct my_struct
{
  Function f;

  my_struct(const Function &f) : f(f) {}
};

Что происходит, когда назначается экземпляр этого типа? Насколько я понимаю, лямбды неизменяемы и удалили операторы присваивания.

Тем не менее, когда я присваиваю объекту этот тип в приведенном ниже фрагменте кода, ошибки не возникает:

// a structure which contains a function;
// possibly a lambda function
template<typename Function>
  struct my_struct
{
  Function f;

  my_struct(const Function &f) : f(f) {}

  // XXX adding this assignment operator causes an error
  //my_struct &operator=(const my_struct &other)
  //{
  //  f = other.f;
  //  return *this;
  //}
};

template<typename Function>
my_struct<Function> make_struct(const Function &f)
{
  return my_struct<Function>(f);
}

int main()
{
  // create some lambda
  auto lambda = [](int x){return x;};

  // make a struct containing a copy of the lambda
  auto x = make_struct(lambda);

  // try to assign to the struct, which
  // presumably assigns to the enclosed lambda
  x = make_struct(lambda);

  return 0;
}

Добавление закомментированного оператора присваивания приводит к ошибке, как и ожидалось:

$ g++-4.6 -std=c++0x test.cpp
test.cpp: In member function ‘my_struct<Function>& my_struct<Function>::operator=(const my_struct<Function>&) [with Function = main()::<lambda(int)>, my_struct<Function> = my_struct<main()::<lambda(int)> >]’:
test.cpp:34:25:   instantiated from here
test.cpp:13:5: error: use of deleted function ‘main()::<lambda(int)>& main()::<lambda(int)>::operator=(const main()::<lambda(int)>&)’
test.cpp:27:18: error: a lambda closure type has a deleted copy assignment operator

Итак, возможно ли создавать присваиваемые типы с переменными лямбда-члена? Это кажется разумным, и стоит попробовать. Рассмотрим, например, объединение лямбды с boost :: transform_iterator .

10
задан Jared Hoberock 12 December 2011 в 21:52
поделиться