Rozważmy następujący kod C++ 11:Czy C++ 11 wymaga aby lambda została uznana za zmienną?
#include <functional>
#include <cstdlib>
template <typename F>
void test(F &&f) {
auto foo = [f]() {
f();
};
foo();
}
int main() {
test(std::bind(std::puts, "hello"));
return 0;
}
GCC i Clang zaakceptować to jako ważnego kodu C++ 11, ale Visual Studio 2013 wymaga lambda należy deklarować zmienne (auto foo = [f]() mutable { ... }
). W przeciwnym razie pojawia się ten błąd:
error C3848: expression having type '
const std::_Bind<true,int,int (__cdecl *const)(const char *),const char (&)[6]>
' would lose some const-volatile qualifiers in order to call 'int std::_Bind<true,int,int (__cdecl *const)(const char *),const char (&)[6]>::operator()<>(void)
'
Czy program Visual Studio ma prawo odrzucić ten kod bez możliwości zmiany, czy też jest poprawny C++ 11?
(ciekawe Clang odrzuca kod po zmianie std::bind(std::puts, "hello")
do std::bind(std::exit, 0)
widocznie ponieważ uważa noreturn
aby funkcja Typ różne;. Jestem pewien, że jest to bug)
Nie, nie jest zgodny ze standardem. "Efektem" g (u1, u2, ..., uM) "będzie" INVOKE (fd, v1, v2, ..., vN, result_of :: type) '" oznacza, że wynik 'bind' musi być możliwy do wywołania, jeśli obiekt funkcji bound jest. Wskaźnik funkcji można wywoływać bez względu na to, czy jest to "const", czy też "bind". –
@MikeSeymour 'g' jest zwracaną wartością' std :: bind', i określone jest tylko zachowanie 'g (...)'. Gdzie standard wymaga wywoływania pomocniczego za pośrednictwem odniesienia "const" do tej wartości zwracanej? – hvd
W cytacie podałem powyżej (20.8.9.1.2/3) oraz następującej klauzuli "gdzie' cv' reprezentuje kwalifikatory cv 'g'". Wywołanie 'g' ma taki sam efekt jak wywołanie' fd' (obiektu powiązanej funkcji) z kwalifikatorami cv 'g' zastosowanymi do' fd'; więc wywołanie do 'const' -kwalifikowanej kopii/odniesienia' g' musi być prawidłowe, jeśli wywołane jest 'const FD'. W tym przypadku 'FD' jest typem wskaźnika funkcji, który można wywoływać niezależnie od tego, czy jest to' const'. –