【发布时间】:2010-09-08 16:24:40
【问题描述】:
我为 C++11 编写了一个小型实用程序类,我将其用作范围保护,以便更轻松地处理异常安全和类似的事情。
看起来有点像黑客。但我很惊讶我没有在其他地方看到它使用 C++11 功能。我认为 boost 在 C++98 中也有类似的东西。
但这是个好主意吗?还是有我遗漏的潜在问题?在 boost 或类似中是否已经有类似的解决方案(具有 C++11 功能)?
namespace detail
{
template<typename T>
class scope_exit : boost::noncopyable
{
public:
explicit scope_exit(T&& exitScope) : exitScope_(std::forward<T>(exitScope)){}
~scope_exit(){try{exitScope_();}catch(...){}}
private:
T exitScope_;
};
template <typename T>
scope_exit<T> create_scope_exit(T&& exitScope)
{
return scope_exit<T>(std::forward<T>(exitScope));
}
}
#define _UTILITY_EXIT_SCOPE_LINENAME_CAT(name, line) name##line
#define _UTILITY_EXIT_SCOPE_LINENAME(name, line) _UTILITY_EXIT_SCOPE_LINENAME_CAT(name, line)
#define UTILITY_SCOPE_EXIT(f) const auto& _UTILITY_EXIT_SCOPE_LINENAME(EXIT, __LINE__) = ::detail::create_scope_exit(f)
它被使用过类似的东西。
int main ()
{
ofstream myfile;
myfile.open ("example.txt");
UTILITY_SCOPE_EXIT([&]{myfile.close();}); // Make sure to close file even in case of exception
myfile << "Writing this to a file.\n"; // Imagine this could throw
return 0;
}
【问题讨论】:
-
您可能想看看我的惰性 RAII 课程:stackoverflow.com/questions/2419650/…。请注意,您的
scope_exit依赖于复制构造函数消除。如果你在没有优化的情况下编译这个 sn-p,你调用 scope-exit lambda 两次。请参阅我的 RAII 课程,了解如何解决该问题。 -
我认为 myfile 超出范围时将被关闭。它应该已经是异常安全的了。
-
这是一个简单的 C++11 范围保护实现,它不依赖于复制构造函数的消除,也不会冒着悬空指向临时对象的风险:stackoverflow.com/a/12545195/558823
-
另一个潜在问题是您为宏使用保留名称...