2017-12-15 6 views
1

Ich bin in der Notwendigkeit, Warnungen loszuwerden, einer davon ist ein -Wingling-sonst. Er stellt fest, ein unsicherer, wenn in der folgenden Makrodefinition:dangling wenn und Makro

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

Ich muss zugeben, ich weiß nicht wirklich in dieses Makro erhalten und somit nicht wissen, wie diese Warnung zu beheben.

Konnte mir jemand mit einer Erklärung helfen, wie man das Dangling sonst vermeidet?

+0

' #define FOR_EACH_REF (var, container) für (auto & var: container) '? – Jarod42

+0

@ Jarod42 Jepp, das ist der Punkt, keine automatischen Variablen und neue Sachen, brauchen alte Compiler-Unterstützung. –

+2

@OliverFriedrich 'auto' ist so alt wie' declltype' ... – Steve

Antwort

2

Sie könnten den Zustand umkehren zu leeren, wenn Block und so problematisch else haben zu vermeiden:

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

Da C++ 11, wäre es auch einfach zu schreiben:

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

überraschend einfach, dass es getan hat. Ich habe die Warnung offensichtlich falsch interpretiert. Vielen Dank. –

+0

Dieses Makro, wie die OP-Version, wird nicht funktionieren, bevor C++ 11 ohne die Hilfe von nicht-standard Compiler-Erweiterungen. 'declltype' wurde in C++ 11 eingeführt. – Peter

2

Wie vermeidet man das Dangling sonst?

Die einfachste (und nicht empfohlene) Option ist das Deaktivieren der Warnung im Compiler mit -Wno-dangling-else.

Die wirkliche Lösung ist Klammern hinzuzufügen, um die if/else Filialen:

#define FOR_EACH_REF(var, container) \ 
    if(bool _cont = true) { \ 
    for(/* ... */) \ 
     if((_cont = false)) {} else { \ 
     for(/* ... */) 

#define FOR_EACH_REF_END }} 

Verbrauch:

FOR_EACH_REF(foo, bar) 
{ 

} 
FOR_EACH_REF_END 

Wenn Sie einen Bereich iterieren wollen, C++ 11 stellt eine Sprachsyntax dafür zur Verfügung, die anstelle dieses abscheulichen Makros verwendet werden sollte:

for(const auto& var : container) { }