Czy w C ++ 11 można utworzyć szablon funkcji lambda? Czy może jest zbyt specyficzny, aby można go było zastosować w szablonie?
Rozumiem, że zamiast tego mogę zdefiniować klasyczną szablonową klasę / funktor, ale pytanie brzmi bardziej: czy język pozwala na tworzenie szablonów funkcji lambda?
Odpowiedzi:
AKTUALIZACJA 2018: C ++ 20 zostanie dostarczony z szablonami i konceptualizowanymi lambdami. Funkcja została już zintegrowana ze standardową wersją roboczą.
AKTUALIZACJA 2014: C ++ 14 został wydany w tym roku i teraz zapewnia polimorficzne lambdy z taką samą składnią jak w tym przykładzie. Niektóre duże kompilatory już to implementują.
Na tym stoi (w C ++ 11), niestety nie. Polimorficzne lambdy byłyby doskonałe pod względem elastyczności i mocy.
Pierwotnym powodem, dla którego ostatecznie stały się monomorficzne, były koncepcje. Pojęcia utrudniały sytuację w tym kodzie:
W szablonie z ograniczeniami możesz wywoływać tylko inne szablony z ograniczeniami. (W przeciwnym razie nie można sprawdzić ograniczeń.) Czy można
foo
wywołaćbar(x)
? Jakie ograniczenia ma lambda (parametr to przecież tylko szablon)?Koncepcje nie były gotowe na rozwiązanie tego rodzaju problemów; wymagałoby to więcej rzeczy
late_check
( np . koncepcja nie była sprawdzana do momentu wywołania) i innych. Łatwiej było porzucić to wszystko i trzymać się monomorficznych lambd.Jednak po usunięciu pojęć z C ++ 0x polimorficzne lambdy ponownie stają się prostą propozycją. Nie mogę jednak znaleźć żadnych propozycji. :(
źródło
C ++ 11 lambda nie może być szablonowane, jak podano w innych odpowiedziach, ale
decltype()
wydaje się, że pomaga, gdy używa się lambda w obrębie klasy lub funkcji opartej na szablonie.Wydruki:
Odkryłem, że ta technika jest pomocna podczas pracy z kodowanym szablonem, ale zdaję sobie sprawę, że nadal oznacza to, że same lambdy nie mogą być szablonowane.
źródło
T
działałby dobrze zamiastdecltype(t)
w tym przykładzie.W C ++ 11 funkcje lambda nie mogą być szablonowane, ale w następnej wersji standardu ISO C ++ (często nazywanej C ++ 14) ta funkcja zostanie wprowadzona. [Źródło]
Przykład użycia:
Zauważ, że chociaż w składni użyto słowa kluczowego
auto
, odliczenie typu nie użyje regułauto
dedukcji typu, ale zamiast tego użyje reguł dedukcji argumentu szablonu. Zobacz także propozycję ogólnych wyrażeń lambda (i jej aktualizację ).źródło
auto
dedukcji typu są zdefiniowane tak, aby były takie same jak reguły dedukcjitemplate
argumentów funkcji.Wiem, że to pytanie dotyczy C ++ 11. Jednak dla tych, którzy wyszukali i wylądowali na tej stronie, szablony lambdas są teraz obsługiwane w C ++ 14 i noszą nazwę Generic Lambdas.
[informacje] Większość popularnych kompilatorów obsługuje teraz tę funkcję. Obsługuje Microsoft Visual Studio 2015. Clang obsługuje. Obsługuje GCC.
źródło
Zastanawiam się co z tym:
Użyłem podobnego kodu, aby wygenerować szablon i zastanawiać się, czy kompilator zoptymalizuje funkcję „zawijania”.
źródło
Spójrz na Boost.Phoenix dla polimorficznych lambd: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html Nie wymaga C ++ 0x przez sposób :)
źródło
Istnieje rozszerzenie gcc, które pozwala na szablony lambda :
gdzie
_widgets
jeststd::tuple< fusion::pair<Key_T, Widget_T>... >
źródło
Bawiłem się najnowszą
version 5.0.1
kompilacją clang z-std=c++17
flagą i teraz jest pewne wsparcie dla parametrów auto type dla lambdas:źródło
Oto jedno rozwiązanie, które polega na zawinięciu lamby w strukturę:
Aby użyć:
Głównym problemem z tym (oprócz dodatkowego pisania) jest to, że nie możesz osadzić tej definicji struktury w innej metodzie lub dostajesz (gcc 4.9)
Próbowałem też to zrobić:
Z nadzieją, że mógłbym to wykorzystać w ten sposób:
Ale pojawia się błąd kompilatora:
Więc to nie działa ... ale nawet gdyby się skompilowało, miałoby to ograniczone zastosowanie, ponieważ nadal musielibyśmy umieścić „używanie LamdaT” w zakresie plików (ponieważ jest to szablon), co w pewnym sensie nie spełnia celu lambdas.
źródło
Nie jestem pewien, dlaczego nikt inny tego nie sugerował, ale możesz napisać funkcję szablonową, która zwraca funkcje lambda. Poniższe rozwiązało mój problem, powód, dla którego przyszedłem na tę stronę:
Teraz, gdy chcę funkcji, która przyjmuje dany typ argumentów (np.
std::string
), Po prostu mówięi teraz
f("any string")
wraca1.0
.To jest przykład tego, co rozumiem przez „wzorcową funkcję lambda”. (Ten szczególny przypadek jest używany do automatycznego zapewniania obojętnej funkcji ważenia, gdy ktoś nie chce ważić swoich danych, niezależnie od ich danych.)
źródło