this presentation 00:19:00頃、Andrei Alexandrescuは彼のSCOPE_EXIT
マクロの実装について説明します。ここで__COUNTER__はODR違反を引き起こしますか?
#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() + [&]()
はこれまでのところ、非常によく知られている(彼も、これは古い帽子であることを彼のスライドで述べている):彼は破壊にラムダを実行スタック上ScopeGuard
オブジェクトを作成します。使い方は次のようになります。
void foo()
{
SCOPE_EXIT{ printf("foo exits"); };
}
しかし1時04分00秒で、チャンドラーCarruthは、インライン関数で使用する場合__COUNTER__
マクロのこの用法は、ODR違反を引き起こす「匿名」の名前を作成することを主張しています。これは本当ですか?このマクロは、型名などではなく、ローカル変数名の作成にのみ使用されるため、ODR違反の原因となるのはなぜですか?
私はちょうどそれが機能自体の定義についてですことを理解することが私にしばらく時間がかかった、同じ結論に達しました。しかし、たとえそれがちょっと変わった変数名であったとしても、これは意味があります。私は誰もこれが問題を引き起こさないことを願っていますね...多分LINEマクロはここでより良い選択でしょうか? – Horstling
はい、1行に複数のものを宣言しない限り、そうです。 (または、 '#line'をつぶっています。) –