2014-06-10 7 views
6

Dieses Problem kam von this question.Unterschiedliches Verhalten zwischen libstdC++ und libC++ beim Erstellen von std :: function mit Lambda

Der folgende Code compiles fine Klirren mit 3.4 mit libstdC++:

#include <functional> 

int main() { 
    std::function<void()> f = []() {}; 
} 

Aber fails miserably mit Klirren 3.4 und libC++:

In file included from main.cpp:1: 
In file included from /usr/include/c++/v1/functional:465: 
In file included from /usr/include/c++/v1/memory:599: 
/usr/include/c++/v1/tuple:320:11: error: rvalue reference to type '<lambda at main.cpp:4:31>' cannot bind to lvalue of type '<lambda at main.cpp:4:31>' 
     : value(__t.get()) 
     ^ ~~~~~~~~~ 
/usr/include/c++/v1/tuple:444:8: note: in instantiation of member function 'std::__1::__tuple_leaf<0, <lambda at main.cpp:4:31> &&, false>::__tuple_leaf' requested here 
struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> 
    ^
/usr/include/c++/v1/functional:1278:26: note: in instantiation of member function 'std::__1::__function::__func<<lambda at main.cpp:4:31>, std::__1::allocator<<lambda at main.cpp:4:31> >, void()>::__func' requested here 
      ::new (__f_) _FF(_VSTD::move(__f)); 
         ^
main.cpp:4:31: note: in instantiation of function template specialization 'std::__1::function<void()>::function<<lambda at main.cpp:4:31> >' requested here 
    std::function<void()> f = []() {}; 
          ^
In file included from main.cpp:1: 
In file included from /usr/include/c++/v1/functional:465: 
In file included from /usr/include/c++/v1/memory:599: 
/usr/include/c++/v1/tuple:321:10: error: static_assert failed "Can not copy a tuple with rvalue reference member" 
     {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");} 
     ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/include/c++/v1/tuple:320:11: error: rvalue reference to type 'allocator<[...]>' cannot bind to lvalue of type 'allocator<[...]>' 
     : value(__t.get()) 
     ^ ~~~~~~~~~ 
/usr/include/c++/v1/tuple:444:8: note: in instantiation of member function 'std::__1::__tuple_leaf<0, std::__1::allocator<<lambda at main.cpp:4:31> > &&, false>::__tuple_leaf' requested here 
struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> 
    ^
/usr/include/c++/v1/functional:1286:34: note: in instantiation of member function 'std::__1::__function::__func<<lambda at main.cpp:4:31>, std::__1::allocator<<lambda at main.cpp:4:31> >, void()>::__func' requested here 
      ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a)); 
           ^
main.cpp:4:31: note: in instantiation of function template specialization 'std::__1::function<void()>::function<<lambda at main.cpp:4:31> >' requested here 
    std::function<void()> f = []() {}; 
          ^
In file included from main.cpp:1: 
In file included from /usr/include/c++/v1/functional:465: 
In file included from /usr/include/c++/v1/memory:599: 
/usr/include/c++/v1/tuple:321:10: error: static_assert failed "Can not copy a tuple with rvalue reference member" 
     {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");} 
     ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
4 errors generated. 

Welches Verhalten ist richtig?

Antwort

7

Ich bin überrascht, dass es Zweifel darüber gibt, welche Implementierung es richtig macht und was es falsch macht; das Snippet sollte natürlich kompilieren. libc++ hat das falsche Verhalten, und unten ist ein Link zum entsprechenden Fehlerbericht.


Hinweis: Bug 17798 hat in neueren Versionen der Bibliothek Implementierung fest.

+0

Ja, einmal auf die '[]() {}' Form reduziert, ist das richtige Verhalten ziemlich offensichtlich. Danke für den Link zum Fehlerbericht. –

Verwandte Themen