C ++ 11中的作用域(失败)?

问题描述 投票:3回答:2

我写了一个非常简单的解决方案,但是有人笑了,发现了一个缺陷,如下所示http://ideone.com/IcWMEf

#include <iostream>
#include <ostream>
#include <functional>
#include <exception>
using namespace std;

// Wrong scope(failure)
class FailBlockT
{
    typedef function<void()> T;
    public:
    T t;
    FailBlockT(T t)
    {
        this->t=t;
    }
    ~FailBlockT()
    {
        if (std::uncaught_exception())
        {
            t();
        }
    }
};

struct Test
{
    ~Test()
    {
        try
        {
            FailBlockT f([]()
            {
                cout << "failure" << endl;
            });
            // there is no any exception here, but "failure" is printed.
            // See output below
        }
        catch(...)
        {
            cout << "some exception" << endl;
        }
    }
};

int main()
{
    try
    {
        Test t;
        throw 1;
    }
    catch(int){}
    return 0;
}

总之,问题是我的代码在std::uncaught_exception()处。当引发异常并执行常规析构函数时。如果我使用范围失败,它将查看std::uncaught_exception()并认为对象范围由于异常而丢失,而不是简单地退出范围。

我想不出任何好的解决方案,通常情况下,VS离开范围并在其中抛出异常。是的,我知道在dtors中扔是一个坏主意,但这就是为什么我未能注意到此问题的原因,因为我从未抛出异常。

我该如何区分/解决这个问题?

c++ exception c++11 destructor
2个回答
3
投票
没有引发异常,但它认为有异常。

4
投票
它基于平台特定的功能uncaught_exception_count。它与标准库中的std :: uncaught_exception相似,但是它不是布尔结果,而是返回unsigned int,显示未捕获的异常的当前计数。
目前已在{Clang 3.2,GCC 3.4.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7,MSVC2005SP1,MSVC2008SP1,MSVC2010SP1,MSVC2012} x {x32,x64}上进行了测试。

在C ++ 11中,以下语法为available

try { int some_var=1; cout << "Case #1: stack unwinding" << endl; scope(exit) { cout << "exit " << some_var << endl; ++some_var; }; scope(failure) { cout << "failure " << some_var << endl; ++some_var; }; scope(success) { cout << "success " << some_var << endl; ++some_var; }; throw 1; } catch(int){} { int some_var=1; cout << "Case #2: normal exit" << endl; scope(exit) { cout << "exit " << some_var << endl; ++some_var; }; scope(failure) { cout << "failure " << some_var << endl; ++some_var; }; scope(success) { cout << "success " << some_var << endl; ++some_var; }; }

在C ++ 98中是[noisier:]]

try { cout << "Case #1: stack unwinding" << endl; BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END throw 1; } catch(int){} { cout << "Case #2: normal exit" << endl; BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END }

此外,库具有UNWINDING_AWARE_DESTRUCTOR功能。 Example

struct DestructorInClass
{
    UNWINDING_AWARE_DESTRUCTOR(DestructorInClass,unwinding)
    {
        cout << "DestructorInClass, unwinding: "
             << ( unwinding ? "true" : "false" ) << endl;
    }
};

但是,在某些情况下,UNWINDING_AWARE_DESTRUCTOR可能会give wrong results(尽管范围(成功)和范围(失败)功能不受此类问题的影响。

© www.soinside.com 2019 - 2024. All rights reserved.