2012-10-05 16 views
8

Potrzebuję utworzyć predykat z funkcji ograniczonego elementu, więc zapakowałem go w boost::function<bool(SomeObject const &)>. Wydaje się, że wszystko jest w porządku i wszystko, ale w jednym przypadku musiałem je zanegować. JednakZawijanie referencji pod C++ 03

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

nie skompilować pod MSVC++ 9.0 (Visual Studio 2008), twierdząc, że odniesienie do odniesienia jest nieprawidłowy:

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 

Problemem jest to, że boost::function definiuje argument_type jak SomeObject const & i std::unary_negate<_Fn1> wystąpienia przez std::not1 wewnętrznie próbuje użyć const typename _Fn1::argument_type&, a kompilator odrzuca go, ponieważ T::argument_type jest już odnośnikiem. Jestem pewien, że to powinno się skompilować pod C++ 11, ale jest to stary kompilator, który jest tylko C++ 03. Więc chciałbym wiedzieć, kto to wina:

  • kompilator, ponieważ powinna ona zapaść odniesienie (apparently not),
  • biblioteka standardowa, ponieważ powinien on być przygotowany do nie obsługiwać funktory biorąc referencje (podobno, ponieważ specyfikacja definiuje unary_negate z const typename Predicate::argument_type& x argument),
  • doładowania, bo argument_type nie powinno być odniesienie nawet gdy rzeczywisty argument jest lub
  • kopalni, bo boost::function nie powinien być stosowany z argumentów referencyjnych?
+0

Czy jest kompilowany pod innymi kompilatorami? – eh9

+0

@ eh9: Z gcc kompiluje, przynajmniej dla celów mingw32 i cygwin. –

+0

@ eh9: Ale to nie jest zbyt istotne dla pytania; kto jest winien i dlaczego zależy od specyfikacji. –

Odpowiedz

1

Usterka z pewnością nie jest wzmocniona; boost::function jest w zasadzie tylko std::function, z tą samą semantyką. I boost::function s przy parametrach odniesienia działają również dobrze. Po prostu nie możesz ich użyć z std::not1 lub resztą rzeczy z <functional>.

Odwołanie do odwołania w C++ 11 powoduje, że std::not1 działa w taki sposób, jak by sobie tego życzył. Sposób, w jaki określono w C++ 03 sposób , nie mógł działać bez zwijania referencji - z wyjątkiem implementacji, w których implementatorzy wykonali trochę twórczej interpretacji, a nie niewolniczo podążali za literą Standardu.

To możliwe aby std::not1 pracy w C++ 03 dodając specjalizacji std::unary_negate dla orzeczników w nawiązaniu argument_type s, ale ani libC++ ani libstdC++ uczyniła.

Ale wiesz kto ma? Zwiększenie! Jeśli po prostu zmienisz kod, aby używać boost::not1 wszędzie tam, gdzie obecnie używasz std::not1, everything will work fine. Zasadniczo pomyśl o przestrzeni nazw boost, tak jakby była to wersja zgodna z C++ 11 z std; wszystko, co działa w przestrzeni nazw C++ 11 std, prawdopodobnie działa w przestrzeni nazw C++ 03: boost.


Zastrzeżenie, miejmy nadzieję off-Temat: Clang kompilator na moim MacBook (Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)) cicho zapada odniesień nawet w trybie -std=c++03, tak że

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

produkuje żadnego błędu.Podczas testowania kodu C++ 03 upewnij się, że nie używasz kompilatora z tym błędem.

Powiązane problemy