【发布时间】:2016-09-13 02:45:06
【问题描述】:
在 00:19:00 左右的 this presentation 中,Andrei Alexandrescu 解释了他的 SCOPE_EXIT 宏的实现。他在堆栈上创建了一个 ScopeGuard 对象,该对象在销毁时执行 lambda:
#define ANONYMOUS_VARIABLE(str) \
CONCATENATE(str, __COUNTER__)
namespace detail {
enum class ScopeGuardOnExit {};
template <typename Fun>
ScopeGuard<Fun>
operator+(ScopeGuardOnExit, Fun&& fn) {
return ScopeGuard<Fun>(std::forward<Fun>(fn));
}
}
#define SCOPE_EXIT \
auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
= ::detail::ScopeGuardOnExit() + [&]()
到目前为止,众所周知(他甚至在幻灯片中说这是一顶旧帽子)。用法如下:
void foo()
{
SCOPE_EXIT{ printf("foo exits"); };
}
但在 01:04:00,Chandler Carruth 声称,当在内联函数中使用 __COUNTER__ 宏来创建“匿名”名称时,会导致 ODR 违规。这是真的吗?宏只用来创建局部变量名,不是类型名什么的,怎么会导致ODR违规呢?
【问题讨论】:
标签: c++ c-preprocessor one-definition-rule