<分区>
对于许多 RAII“守卫” 类,实例化为匿名变量根本没有意义:
{
std::lock_guard<std::mutex>{some_mutex};
// Does not protect the scope!
// The unnamed instance is immediately destroyed.
}
{
scope_guard{[]{ cleanup(); }};
// `cleanup()` is executed immediately!
// The unnamed instance is immediately destroyed.
}
来自 this article :
Anonymous variables in C++ have “expression scope”, meaning they are destroyed at the end of the expression in which they are created.
有什么方法可以防止用户在没有名字的情况下实例化它们吗? (“防止”可能太强了 - “让它变得非常困难”也是可以接受的)。 em>
我可以想到两种可能的解决方法,但它们会在类的使用中引入语法开销:
将类隐藏在
detail
命名空间中并提供一个宏。namespace detail { class my_guard { /* ... */ }; }; #define SOME_LIB_MY_GUARD(...) \ detail::my_guard MY_GUARD_UNIQUE_NAME(__LINE__) {__VA_ARGS__}
这有效,但是hackish。
只允许用户通过高阶函数使用守卫。
template <typename TArgTuple, typename TF> decltype(auto) with_guard(TArgTuple&& guardCtorArgs, TF&& f) { make_from_tuple<detail::my_guard>(std::forward<TArgTuple>(guardCtorArgs)); f(); }
用法:
with_guard(std::forward_as_tuple(some_mutex), [&] { // ... });
当保护类的初始化具有“流畅”语法时,此解决方法不起作用:
{ auto _ = guard_creator() .some_setting(1) .some_setting(2) .create(); }
有没有更好的选择?我可以访问 C++17 功能。