Я сделал наконец симулятор с использованием лямбды в C ++ 11, как показано ниже:
#include <cstdio>
template<typename Functor>
struct Finalizer
{
Finalizer(Functor& func) : func_(func) {} // (1)
~Finalizer() { func_(); }
private:
Functor func_; // (2)
};
template<typename functor>
Finalizer<functor> finally(functor& func)
{
return Finalizer<functor>(func); (3)
}
int main()
{
int a = 20;
// print the value of a at the escape of the scope
auto finalizer = finally([&]{ printf("%d\n", a); }); // (4)
}
Код работает, как и предполагалось, но есть нежелательный вызов ctor для копирования (лямбда-функтора)) в ctor Финализатор struct (1).(К счастью, RVO избегает создания копии в операторе возврата в функции finally (3 -> 4).)
Компилятор не устраняет вызов копирования ctor (по крайней мере, в vc10- gcc может оптимизировать его), и если тип функтора в Finalizer struct (2) будет изменен, чтобы ссылаться на него, он потерпит крах, поскольку аргумент lambda при вызове finally (4)) - это r-значение.
Конечно, код можно «оптимизировать», как показано ниже
template<typename Functor>
struct Finalizer
{
Finalizer(Functor& func) : func_(func) {}
~Finalizer() { func_(); }
private:
Functor& func_;
};
int main()
{
int a = 20;
auto finalizer = [&]{ printf("%d\n", a); };
Finalizer<decltype(finalizer)> fin(finalizer);
}
Никаких накладных расходов, только вызов printf выполняется в концеобласти видимостиНо ... мне это не нравится.:( Я пытался обернуть его макросом, но ему нужно объявить два «имени» - одно для лямбда-объекта, другое для объекта финализатора.
Моя цель проста -
- Все ненужные издержки производительности, которых можно избежать, должны быть исключены. В идеале не должно быть вызова функции, каждая процедура должна быть встроенной.
- Сохранять краткое выражение в качестве цели вспомогательной функции. Использование макроса разрешено, но обескуражен.
Есть ли какое-нибудь решение, чтобы избежать этого в этой ситуации?