Ostatnio natknąłem się na następujący ezoteryczny fragment kodu.
int main(){(([](){})());}
Sformatuj go w następujący sposób, aby był bardziej czytelny:
int main(){
(([](){})()); // Um... what?!?!
}
Ale nie mogę się zastanowić, jak (([](){})())
ważny jest kod.
- Nie wygląda na składnię wskaźnika funkcji.
- To nie może być jakiś sposób na przeciążenie operatora. Kod kompiluje się w obecnej postaci.
Google niewiele pomogło w tym wyszukiwaniu wszystkich symboli. Ale kompiluje się w Visual Studio 2010 i nic nie wyświetla. Nie było błędów ani ostrzeżeń. Wygląda to na prawidłowy kod.
Nigdy nie widziałem żadnego ważnego kodu, który jest tak dziwaczna poza Javascript i C wskaźników funkcji .
Czy ktoś może wyjaśnić, jak to jest poprawne C ++?
Don't sweat it. We have int main(){(([](){})());} which is valid C++"
(9 listopada na czacie)Odpowiedzi:
Kod zasadniczo nazywa pustą lambda.
Zacznijmy od początku:
[](){}
jest pustym wyrażeniem lambda .Następnie w C i C ++ możesz zawijać wyrażenia w pareny i zachowują się dokładnie tak samo † jak gdyby zostały napisane bez nich, więc to właśnie robi pierwsza para parenów wokół lambdy. Jesteśmy teraz na
([](){})
.Następnie,
()
po pierwszym zawijaniu parens wywołuje (pustą) lambda. Jesteśmy teraz na([](){})()
Całe wyrażenie jest ponownie owinięte w pareny i otrzymujemy
(([](){})())
.W końcu
;
kończy się wypowiedź. Dojeżdżamy do(([](){})());
.† Istnieją pewne przypadki narożne przynajmniej w C ++, na przykład z
T a_var;
różnicą międzydecltype(a_var)
idecltype((a_var))
.źródło
B foo(A())
foo jest funkcją (przyjmowanie wskaźnika do funkcji jako jedynego parametru i zwracanie B), podczas gdy wB foo((A()))
foo jest to obiekt B skonstruowany przy użyciu konstruktora obiekt A (która instancja jest w tym przypadku anonimową tymczasową).