безопасность исключений — C ++: почему работает этот простой Scope Guard?

Пока что каждый, кто рассматривал область видимости, имеет логическую переменную guard. Например, посмотрите это обсуждение:
Самый простой и изящный с ++ 11 ScopeGuard

Но работает простой охранник (gcc 4.9, clang 3.6.0):

template <class C>
struct finally_t : public C {
finally_t(C&& c): C(c) {}
~finally_t() { (*this)(); }
};
template <class C>
static finally_t<C> finally_create(C&& c) {
return std::forward<C>(c);
}
#define FINCAT_(a, b) a ## b
#define FINCAT(a, b) FINCAT_(a, b)
#define FINALLY(...) auto FINCAT(FINALY_, __LINE__) = \
finally_create([=](){ __VA_ARGS__ })

int main() {
int a = 1;
FINALLY( std::cout << "hello" << a << std::endl ; );
FINALLY( std::cout << "world" << a << std::endl ; );
return 0;
}

Почему не уничтожены временные копии? Опасно ли полагаться на это поведение?

9

Решение

Вы наблюдаете эффекты Copy Elision (или Move Elision, в данном случае). Копирование Elision не гарантируется / не обязательно, но обычно выполняется основными компиляторами даже при компиляции без оптимизации. Попробуйте gcc -fno-elide-constructors, чтобы увидеть, что он «сломался»: http://melpon.org/wandbox/permlink/B73EuYYKGYFMnJtR

1

Другие решения


По вопросам рекламы [email protected]