Link collapses under C ++ 03

I need to create a predicate from a related member function, so I wrapped it in boost::function<bool(SomeObject const &)> . Everything seems to be fine, and that’s all, but I also had to deny it in one case. but

 boost::function<bool(SomeObject const &)> pred; std::not1(pred); 

It does not compile under MSVC ++ 9.0 (Visual Studio 2008), complaining that the link to the link is invalid:

 C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : warning C4181: qualifier applied to reference type; ignored C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : error C2529: '_Left' : reference to reference is illegal 

The problem is that boost::function defines argument_type as SomeObject const & , while std::unary_negate<_Fn1> created by std::not1 tries to use const typename _Fn1::argument_type& , and the compiler rejects it because T::argument_type already a link. I am sure that this should compile under C ++ 11, but this is an old compiler that is only C ++ 03. Therefore, I would like to know who is to blame:

  • the compiler, because it should collapse the link (apparently not) ,
  • standard library, because it should be ready to handle functors that take references (apparently not, because the specification defines unary_negate with the argument const typename Predicate::argument_type& x ),
  • boost because argument_type should not be referenced even if the actual argument is equal to or
  • mine, because boost::function should not be used with reference arguments?
+8
c ++ 03 visual-c ++ - 2008
source share
1 answer

The error, of course, is not Boost; boost::function is basically just std::function with all the semantics. And boost::function , where the reference parameters work fine. You simply cannot use them with std::not1 or the rest of the <functional> .

C ++ 11 reference-collapsing makes std::not1 work the way you think. The method std::not1 was specified in C ++ 03, it may not have worked without link-collapsing - except for implementations when the developers interpreted the creative interpretation a bit, rather than slavishly following the letter of the standard.

You can make std::not1 work in C ++ 03 by adding the specialization std::unary_negate for predicates with the argument_type s reference, but neither lib ++ nor libstd ++ did this.

But do you know who? Boost If you just changed your code to use boost::not1 wherever you use std::not1 , everything will work fine. Basically, think of the boost namespace, as if it were a version compatible with C ++ 11 std ; everything that works in the C ++ 11 std probably works in the C ++ 03 boost namespace.


A Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) , I hope, is off topic: the Clang compiler on my Macbook ( Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) ) silently destroys links even in -std=c++03 mode, so

 typedef const int& ref; typedef const ref& ref2; 

does not cause errors. When you check your C ++ 03 code, make sure you are not using the compiler with this error.

+1
source share

All Articles