2013-01-19 8 views
7

Während mit C++ 11 neue Funktionen experimentieren, entdeckte ich, dass die std :: Platzhalter :: _ 1 nicht direkt als Lambda-Ausdrücke verwendet werden können:mit C++ 11 Platzhalter als Lambdas?

#include <algorithm> 
#include <functional> 
// #include <boost/lambda/lambda.hpp> 

using namespace std; 
// using boost::lambda::_1; 
using std::placeholders::_1; 

int main() 
{ 
    int a[] = {1,2,3,4,5}; 

    transform(a, a+5, a, _1 * 2); 
} 

Clang 3.3 Fehler:

tmp $ clang -std=c++11 -stdlib=libc++ -lc++ test.cpp 
test.cpp:16:27: error: invalid operands to binary expression ('__ph<1>' and 'int') 
    transform(a, a+5, a, _1 * 2); 

Wenn ich es ändere, um Boosts Version zu verwenden, kompiliert es sich gut.

Warum funktioniert das nicht mit der Standardversion? Gibt es eine Möglichkeit, es zum Laufen zu bringen oder muss ich hier ein hässliches Lambda verwenden?

transform(a, a+5, a, [](int i){return i*2;}); 

Antwort

7

-Boost hat tatsächlich eine Reihe von _1 Platzhalter. Die von Boost.Bind (die mehr oder weniger in C++ 11 integriert waren), die von Boost.Lambda und sogar die von Lambdas Nachfolger Boost.Phoenix.

Die Lambda und Phoenix-Versionen sind die nur Platzhalter, die verwendet werden können, functors selbst zu erstellen. Die Boost.Bind _1 Platzhalter können nicht, und das ist, was standardisiert wurde. Lambda und Phoenix sind Wege, einen Ausdruck in eine Funktion zu verwandeln; Bindung ist einfach ein Funktionsbindungs- und Argumentanpassungssystem.

+0

Ich sehe. Wäre es schwer/schlecht, ein Äquivalent von Boost zu implementieren: Lambda/Phönix mit dem neuen Lambda-System? – ogoid

+0

@ogoid: Äh, * was * neues Lambda-System? Sie fragen auch nach einer ganz anderen Frage. –

+0

@ogoid: Es wäre ziemlich schwierig für mich, Boost.Lambda neu zu erfinden, ich weiß aber nicht von dir. – Mehrdad