悬挂 if 和宏
dangling if and macro
我需要摆脱警告,其中之一是 -Wdangling-else。它在以下宏定义中记录了一个悬空 if:
#define FOR_EACH_REF(var, container) \
if(bool _cont = true) \
for(our::remove_reference<decltype(container)>::type::iterator _it = (container).begin(); _it != (container).end() && _cont; ++_it) \
if((_cont = false)) {} else \
for(our::remove_reference<decltype(container)>::type::value_type& var = *_it; !_cont; _cont = true)
我必须承认,我并没有真正了解这个宏,因此不知道如何解决这个警告。
谁能帮我解释一下如何避免 else 悬空?
how to avoid the dangling else?
最简单(但不推荐)的选项是使用 -Wno-dangling-else
在编译器中禁用警告。
真正的解决方案是在 if
/else
分支周围添加大括号:
#define FOR_EACH_REF(var, container) \
if(bool _cont = true) { \
for(/* ... */) \
if((_cont = false)) {} else { \
for(/* ... */)
#define FOR_EACH_REF_END }}
用法:
FOR_EACH_REF(foo, bar)
{
}
FOR_EACH_REF_END
如果你想迭代一个范围,C++11 提供了相应的语言语法,应该使用它来代替这个可恶的宏:
for(const auto& var : container) { }
您可以反转条件以避免出现空的 if 块并因此出现问题 else
:
#define FOR_EACH_REF(var, container) \
if (bool _cont = true) \
for(our::remove_reference<decltype(container)>::type::iterator _it = (container).begin(); _it != (container).end() && _cont; ++_it) \
if(!(_cont = false)) \
for(our::remove_reference<decltype(container)>::type::value_type& var = *_it; !_cont; _cont = true)
从 C++11 开始,甚至可以很容易地编写:
#define FOR_EACH_REF(var, container) for (auto& var : container)
我需要摆脱警告,其中之一是 -Wdangling-else。它在以下宏定义中记录了一个悬空 if:
#define FOR_EACH_REF(var, container) \
if(bool _cont = true) \
for(our::remove_reference<decltype(container)>::type::iterator _it = (container).begin(); _it != (container).end() && _cont; ++_it) \
if((_cont = false)) {} else \
for(our::remove_reference<decltype(container)>::type::value_type& var = *_it; !_cont; _cont = true)
我必须承认,我并没有真正了解这个宏,因此不知道如何解决这个警告。
谁能帮我解释一下如何避免 else 悬空?
how to avoid the dangling else?
最简单(但不推荐)的选项是使用 -Wno-dangling-else
在编译器中禁用警告。
真正的解决方案是在 if
/else
分支周围添加大括号:
#define FOR_EACH_REF(var, container) \
if(bool _cont = true) { \
for(/* ... */) \
if((_cont = false)) {} else { \
for(/* ... */)
#define FOR_EACH_REF_END }}
用法:
FOR_EACH_REF(foo, bar)
{
}
FOR_EACH_REF_END
如果你想迭代一个范围,C++11 提供了相应的语言语法,应该使用它来代替这个可恶的宏:
for(const auto& var : container) { }
您可以反转条件以避免出现空的 if 块并因此出现问题 else
:
#define FOR_EACH_REF(var, container) \
if (bool _cont = true) \
for(our::remove_reference<decltype(container)>::type::iterator _it = (container).begin(); _it != (container).end() && _cont; ++_it) \
if(!(_cont = false)) \
for(our::remove_reference<decltype(container)>::type::value_type& var = *_it; !_cont; _cont = true)
从 C++11 开始,甚至可以很容易地编写:
#define FOR_EACH_REF(var, container) for (auto& var : container)