Можно ли избежать копирования лямбда-функтора в этой ситуации?

Я сделал симулятор finally с использованием лямбда-выражения в 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 структуры Finalizer struct (1). (К счастью, RVO избегает конструкции копирования в операторе return в функции finally (3 -> 4).)

Компилятор не устраняет вызов copy ctor (по крайней мере, в vc10 - gcc может его оптимизировать), и если тип функтора в Finalizer struct (2) будет изменен на ссылку, он будет сбой, поскольку лямбда-аргумент в вызове 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 помещается в конец области видимости. Но ... мне это не нравится. :( Я пытался обернуть его макросом, но он должен объявить два «имени» - одно для лямбда-объекта, другое для объекта-финализатора.

Моя цель проста -

  1. Все ненужные накладные расходы на производительность, которых можно избежать следует исключить. В идеале, не должно быть вызова функции, каждая процедура должна быть встроена.
  2. Сохраните краткое выражение в качестве цели служебной функции. Использование макроса разрешено, но не рекомендуется.

Есть ли какое-либо решение для избежать этого в этой ситуации?

5
задан summerlight 18 January 2012 в 01:07
поделиться