Я думал о хранении lambda С++ в последнее время. Стандартный совет, который вы видите в Интернете, - это хранить лямбда в объекте 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:: function. И, наконец, мы уничтожаем тестовый объект.
Излишне говорить, что это не то, что я вижу. Когда я компилирую это на Visual С++ 2010 (режим выпуска или отладки), я получаю этот вывод:
Constructing simple!
Copying simple!
Copying simple!
Copying simple!
Copying simple!
Destroying simple!
Destroying simple!
Destroying simple!
5
Destroying simple!
Destroying simple!
Святое дерьмо, что неэффективно! Мало того, что компилятор не смог использовать мой конструктор перемещения, но он сгенерировал и уничтожил две, по-видимому, лишние копии лямбда во время назначения.
Итак, здесь, наконец, есть вопросы: (1) Действительно ли все это копирование действительно необходимо? (2) Есть ли способ принудить компилятор к созданию лучшего кода? Спасибо за чтение!