使用ScopeGuard for SCOPE_FAIL进行声明式编程

时间:2018-12-17 18:22:36

标签: c++ uncaught-exception scopeguard

我正在浏览https://github.com/CppCon/CppCon2015/blob/master/Presentations/Declarative%20Control%20Flow/Declarative%20Control%20Flow%20-%20Andrei%20Alexandrescu%20-%20CppCon%202015.pdf

上Andrei Alexandrescu演讲的幻灯片

我正在尝试从Visual Studio 2017的幻灯片中获取示例,但未获得所需的行为。

void copyFileTransact(const bf::path &from, const bf::path &to)
{
    bf::path temp = std::string("temp.deleteme");
    SCOPE_FAIL{ ::remove(temp.string().c_str()); };
    bf::copy_file(from, temp);
    bf::rename(temp, to);
}

SCOPE_FAIL宏定义如幻灯片中所述。

class UncaughtExceptionCounter
{

public:

UncaughtExceptionCounter() : exceptionCount_(std::uncaught_exceptions()) {}

bool isNewUncaughtException() noexcept
{
    return std::uncaught_exceptions() > exceptionCount_;
}

private:
int exceptionCount_;
};

template <typename FunctionType>
class ScopeGuardForNewException
{
public:

explicit ScopeGuardForNewException(const FunctionType & fun) : 
function_(fun){}

explicit ScopeGuardForNewException(FunctionType && fun) : 
function_(std::move(fun)) {}

~ScopeGuardForNewException() 
{
    if (exceptionCounter_.isNewUncaughtException())
        function_();
}

private:
FunctionType function_;
UncaughtExceptionCounter exceptionCounter_;
};

enum class ScopeGuardOnFail {};

template <typename FunctionType>
ScopeGuardForNewException<typename std::decay<FunctionType>::type> operator 
+ (ScopeGuardOnFail, FunctionType && fun)
{
    return ScopeGuardForNewException<typename 
    std::decay<FunctionType>::type> 
    (std::forward<FunctionType>(fun));
}

#define CONCATENATE_IMPL(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)

#ifdef __COUNTER__
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif

#define SCOPE_FAIL auto ANONYMOUS_VARIABLE(SCOPE_FAIL_STATE) = 
::detail::ScopeGuardOnFail() + [&]()

我希望在给copyFileTransact()提供一些无效路径时,应该执行SCOPE_FAIL宏,因为bf :: copy_file失败了。 但是,在SCOPE_FAIL的ScopeGuard定义中,未捕获的异常数仍为0。

我不明白,当bf :: copy_file失败时将如何引发该异常,并将其计为uncaught_exception?

0 个答案:

没有答案