C++ C++;:为什么这个简单的范围保护工作?

C++ C++;:为什么这个简单的范围保护工作?,c++,exception-safety,scopeguard,C++,Exception Safety,Scopeguard,到目前为止,每个范围保护都有一个保护布尔变量。例如,请参见以下讨论: 但是一个简单的防护装置可以工作(gcc 4.9,clang 3.6.0): 模板 结构最终\u t:public{ 最后_t(C&&C):C(C){ ~finally_t(){(*this)(;} }; 模板 静态最终创建(C&&C){ 返回std::转发(c); } #定义FINCAT(a,b)a##b #定义FINCAT(a,b)FINCAT(a,b) #最终定义(…)自动FINCAT(最终定义,行定义)=\ 最后创建(

到目前为止,每个范围保护都有一个保护布尔变量。例如,请参见以下讨论:

但是一个简单的防护装置可以工作(gcc 4.9,clang 3.6.0):

模板
结构最终\u t:public{
最后_t(C&&C):C(C){
~finally_t(){(*this)(;}
};
模板
静态最终创建(C&&C){
返回std::转发(c);
}
#定义FINCAT(a,b)a##b
#定义FINCAT(a,b)FINCAT(a,b)
#最终定义(…)自动FINCAT(最终定义,行定义)=\
最后创建([=](){{uuuu VA_ARGS})
int main(){
INTA=1;

最后(std::cout您正在观察复制省略(本例中为移动省略)的效果。复制省略不是保证/强制的,但通常由主要编译器执行,即使在编译w/o优化时也是如此。请尝试gcc的-fno-elide构造函数查看它的“中断”:

您正在观察复制省略的效果(本例中为移动省略)。复制省略不是保证/强制的,但通常由主要编译器执行,即使在编译w/o优化时也是如此。请尝试gcc的
-fno elide构造函数以查看它是否“中断”:有一个技巧不依赖于复制省略,只需要很少的更改。以下是您不依赖复制省略的版本。
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;
}