297 Stimmen

Können Lambda-Funktionen als Vorlage verwendet werden?

Gibt es in C++11 eine Möglichkeit, eine Lambda-Funktion als Vorlage zu verwenden? Oder ist sie von Natur aus zu spezifisch, um als Vorlage verwendet zu werden?

Ich verstehe, dass ich eine klassische Vorlage Klasse/Functor stattdessen definieren kann, aber die Frage ist mehr wie: erlaubt die Sprache Vorlage Lambda-Funktionen?

0 Stimmen

Gibt es einen Anwendungsfall, bei dem eine Lambda-Vorlage nützlich wäre?

13 Stimmen

James: Sie könnten eine Funktion erstellen, die über ein Tupel iteriert (nicht unbedingt nützlich).

0 Stimmen

Ich kam auf die Idee, als ich ein Interview von Stroustrup las, in dem er über die Komplexität von Meta-Templates sprach, die ein Problem darstellt. Wenn es erlaubt wäre, stellte ich mir den Ninja-Code-Fu vor, der von allzu cleveren Programmierern erfunden werden könnte, die mit dieser Funktionskombination spielen...

219voto

GManNickG Punkte 476445

UPDATE 2018: C++20 wird mit schablonierten und konzeptualisierten Lambdas kommen. Die Funktion wurde bereits in den Standardentwurf integriert.


UPDATE 2014: C++14 wurde dieses Jahr veröffentlicht und bietet nun polymorphe Lambdas mit der gleichen Syntax wie in diesem Beispiel. Einige wichtige Compiler implementieren sie bereits.


Zum jetzigen Zeitpunkt (in C++11) leider nicht. Polymorphe Lambdas wären im Hinblick auf Flexibilität und Leistung ausgezeichnet.

Der ursprüngliche Grund dafür, dass sie monomorph sind, waren die Konzepte. Die Konzepte machten diese Codesituation schwierig:

template <Constraint T>
void foo(T x)
{
    auto bar = [](auto x){}; // imaginary syntax
}

In einer eingeschränkten Vorlage können Sie nur andere eingeschränkte Vorlagen aufrufen. (Andernfalls könnten die Beschränkungen nicht überprüft werden.) Kann foo aufrufen. bar(x) ? Welche Einschränkungen hat das Lambda (der Parameter dafür ist ja nur eine Vorlage)?

Die Konzepte waren nicht bereit, diese Art von Dingen in Angriff zu nehmen; es würde mehr Dinge erfordern wie late_check (wobei das Konzept erst beim Aufruf geprüft wurde) und so weiter. Einfacher war es, das alles fallen zu lassen und bei monomorphen Lambdas zu bleiben.

Mit der Abschaffung der Konzepte in C++0x werden polymorphe Lambdas jedoch wieder zu einem einfachen Vorschlag. Ich kann jedoch keine Vorschläge dafür finden :(

92voto

shilch Punkte 985

In C++20 ist dies mit der folgenden Syntax möglich:

auto lambda = []<typename T>(T t){
    // do something
};

39voto

Joel Punkte 2820

C++11-Lambdas können nicht wie in anderen Antworten angegeben als Vorlage verwendet werden, aber decltype() scheint zu helfen, wenn ein Lambda innerhalb einer Templated-Klasse oder -Funktion verwendet wird.

#include <iostream>
#include <string>

using namespace std;

template<typename T>
void boring_template_fn(T t){
    auto identity = [](decltype(t) t){ return t;};
    std::cout << identity(t) << std::endl;
}

int main(int argc, char *argv[]) {
    std::string s("My string");
    boring_template_fn(s);
    boring_template_fn(1024);
    boring_template_fn(true);
}

Drucke:

My string
1024
1

Ich habe festgestellt, dass diese Technik hilft, wenn die Arbeit mit Template-Code, aber erkennen, dass es immer noch bedeutet, Lambdas selbst kann nicht Templated werden.

29voto

Timo Türschmann Punkte 4028

In C++11 können Lambda-Funktionen nicht als Vorlage verwendet werden, aber in der nächsten Version des ISO C++-Standards (oft als C++14 bezeichnet) wird diese Funktion eingeführt. [Quelle]

Beispiel für die Verwendung:

auto get_container_size = [] (auto container) { return container.size(); };

Beachten Sie, dass die Syntax zwar das Schlüsselwort auto wird die Typisierung nicht nach den Regeln von auto Typabzug, sondern verwenden stattdessen die Regeln für den Abzug von Vorlagenargumenten. Siehe auch die Vorschlag für generische Lambda-Ausdrücke (und die Update dazu).

10voto

Ram Punkte 2895

Ich bin mir bewusst, dass sich diese Frage auf C++11 bezieht, aber für diejenigen, die gegoogelt haben und auf dieser Seite gelandet sind, werden Templated Lambdas jetzt in C++14 unterstützt und tragen den Namen Generic Lambdas.

[info] Die meisten gängigen Compiler unterstützen diese Funktion jetzt. Microsoft Visual Studio 2015 unterstützt. Clang unterstützt. GCC unterstützt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X