Referenzkollaps unter C ++ 03

8

Ich muss ein Prädikat aus der gebundenen Elementfunktion erstellen, also habe ich es in ein boost::function<bool(SomeObject const &)> eingepackt. Das scheint in Ordnung zu sein und alles, aber ich musste es auch in einem Fall negieren. Jedoch

%Vor%

kompiliert nicht unter MSVC ++ 9.0 (Visual Studio 2008) und beschwert sich, dass der Verweis auf die Referenz ungültig ist:

%Vor%

Das Problem ist, dass boost::function das argument_type als SomeObject const & definiert und das std::unary_negate<_Fn1> instanziiert von std::not1 versucht intern const typename _Fn1::argument_type& zu verwenden und der Compiler lehnt es ab, weil T::argument_type bereits eine Referenz ist. Ich bin mir sicher, dass das unter C ++ 11 kompiliert werden sollte, aber das ist ein alter Compiler, der nur C ++ 03 ist. Also würde ich gerne wissen, wer daran schuld ist:

  • der Compiler, weil der Verweis (anscheinend nicht) ,
  • minimiert werden sollte
  • die Standard-Bibliothek, weil es bereit sein sollte, mit Funktoren umzugehen, die Referenzen verwenden (anscheinend nicht, weil die Spezifikation unary_negate mit const typename Predicate::argument_type& x -Argument definiert),
  • boost's, weil argument_type auch dann keine Referenz sein sollte, wenn das tatsächliche Argument
  • ist
  • meins, weil boost::function nicht mit Referenzargumenten verwendet werden sollte?
Jan Hudec 05.10.2012, 11:05
quelle

1 Antwort

1

Der Fehler ist sicherlich nicht Boosts; boost::function ist im Grunde nur std::function , mit der gleichen Semantik. Und boost::function s mit Referenzparametern funktionieren ebenfalls gut. Sie können sie nur nicht mit std::not1 oder dem Rest des <functional> stuff verwenden.

C ++ 11s Referenz-Kollaps macht std::not1 so, wie Sie es sich denken. Die Art und Weise, wie std::not1 in C ++ 03 angegeben wurde, könnte ohne Referenz-Kollaps nicht funktionieren - außer in Implementierungen, bei denen die Implementierer ein wenig kreative Interpretation vornahmen und nicht sklavisch dem Buchstaben des Standards folgten.

Es ist möglich , dass std::not1 in C ++ 03 arbeitet, indem eine Spezialisierung von std::unary_negate für Prädikate mit dem Verweis argument_type s hinzugefügt wird, aber weder libc ++ noch libstdc ++ / p>

Aber Sie wissen, wer hat? Boost! Wenn Sie nur Ihren Code ändern, um boost::not1 überall dort zu verwenden, wo Sie derzeit std::not1 verwenden, Alles wird gut funktionieren. Im Grunde denken Sie an den Namensraum boost , als wäre es eine C ++ 11-kompatible Version von std ; Alles, was in C ++ 11s std -Namespace funktioniert, funktioniert wahrscheinlich in C ++ 03s boost -Namespace.

Vorbehalt, hoffentlich off-topic: Der Clang-Compiler auf meinem Macbook ( Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) ) kollabiert die Referenzen sogar im -std=c++03 -Modus, so dass

%Vor%

erzeugt keinen Fehler. Stellen Sie sicher, dass Sie keinen Compiler mit diesem falschen Feature verwenden, wenn Sie Ihren C ++ 03-Code testen.

    
Quuxplusone 10.11.2013, 04:25
quelle

Tags und Links