2017-12-15 11 views
1

경고가 필요 없으며, 그 중 하나가 -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) 

내가 인정해야, 난 정말이 매크로로하지 않으며, 따라서이 경고를 해결하는 방법을 알고하지 않습니다 : 그것은 다음과 같은 매크로 정의 내부의 경우 매달려 말한다.

다른 사람이 매달리는 것을 피하는 방법에 대한 설명이 도움이 될 수 있습니까?

+0

' #define FOR_EACH_REF (var, container) for (auto & var : container)'? – Jarod42

+0

@ Jarod42 jepp, 그게 포인트, 아니 자동 변수와 새로운 것들, 오래된 컴파일러 지원이 필요합니다. –

+2

@OliverFriedrich'auto'는'decltype'만큼 오래되었습니다 ... – Steve

답변

2

이 비어있는 경우 블록 등 문제가 else 가지고 : C++ 11 이후

#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) 

을, 심지어는 쓰기 쉬운 것입니다 :

#define FOR_EACH_REF(var, container) for (auto& var : container) 
+0

놀라 울 정도로 쉽게 할 수 있습니다. 나는 분명히 잘못된 라인에 경고를 해석했다. 고맙습니다. –

+0

OP의 버전과 마찬가지로이 매크로는 비표준 컴파일러 확장없이 C++ 11보다 먼저 작동하지 않습니다. 'decltype'은 C++ 11에서 소개되었습니다. – Peter

2

다른 방법은 어떻게 피합니까?

가장 쉬운 (권장하지 않는) 옵션은 컴파일러에서 -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) 이에 대한 언어 구문을 제공하며이 매크로는이 가증 한 매크로 대신 사용해야합니다.

당신은 피하기 위해 조건을 반전 할 수