В последнее время я думаю о хранении лямбды C ++. Стандартный совет, который вы видите в Интернете, - хранить лямбду в объекте std :: function. Тем не менее, ни один из этих советов никогда не рассматривает последствия хранения. Мне пришло в голову, что должно быть какое-то серьезное вуду за кулисами, чтобы сделать эту работу. Рассмотрим следующий класс, в котором хранится целочисленное значение:
class Simple {
public:
Simple( int value ) { puts( "Constructing simple!" ); this->value = value; }
Simple( const Simple& rhs ) { puts( "Copying simple!" ); this->value = rhs.value; }
Simple( Simple&& rhs ) { puts( "Moving simple!" ); this->value = rhs.value; }
~Simple() { puts( "Destroying simple!" ); }
int Get() const { return this->value; }
private:
int value;
};
Теперь рассмотрим эту простую программу:
int main()
{
Simple test( 5 );
std::function<int ()> f =
[test] ()
{
return test.Get();
};
printf( "%d\n", f() );
}
Это вывод, который я надеюсь увидеть из этой программы:
Constructing simple!
Copying simple!
Moving simple!
Destroying simple!
5
Destroying simple!
Destroying simple!
Сначала мы создадим тест значения. Мы создаем локальную копию в стеке для временного лямбда-объекта. Затем мы перемещаем временный лямбда-объект в память, выделенную std :: function. Мы уничтожаем временную лямбду. Мы печатаем нашу продукцию. Мы уничтожаем функцию std ::. И, наконец, мы уничтожаем тестовый объект.
Излишне говорить, что это не , что я вижу. Когда я компилирую это в Visual C ++ 2010 (выпуск или режим отладки), я получаю такой вывод:
Constructing simple!
Copying simple!
Copying simple!
Copying simple!
Copying simple!
Destroying simple!
Destroying simple!
Destroying simple!
5
Destroying simple!
Destroying simple!
Святое дерьмо, которое неэффективно! Компилятор не только не смог использовать мой конструктор перемещения, но и сгенерировал и уничтожил две явно лишние копии лямбды во время назначения.
Итак, вот, наконец, вопросы: (1) действительно ли необходимо все это копирование? (2) Есть ли какой-нибудь способ заставить компилятор генерировать лучший код? Спасибо за чтение!