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
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:
unary_negate
mit const typename Predicate::argument_type& x
-Argument definiert), argument_type
auch dann keine Referenz sein sollte, wenn das tatsächliche Argument boost::function
nicht mit Referenzargumenten verwendet werden sollte? 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
erzeugt keinen Fehler. Stellen Sie sicher, dass Sie keinen Compiler mit diesem falschen Feature verwenden, wenn Sie Ihren C ++ 03-Code testen.
Tags und Links c++03 visual-c++-2008