Niedawno zainteresowałem się boost-em i spośród tego co oferuje za bardzo użyteczne uważam wyrażenia lamba , o których można powiedzieć ,że stanowią poszerzenie możliwości samego języka C++.Bardzo mnie się podoba to co dzięki lamba można osiągnąć- znaczne skrócenie kodu i uczynienie go lepiej czytelnym poprzez definicje obiektów funkcyjnych w miejscu przekazywania ich do funkcji uogólnionych stl-a.We większości przypadków nie mam pojęcia jak to działa a zwłaszcza w jaki sposób
jest określany typ wartości zwracanej po utworzeniu funktora z wyrażeniami arytmetycznymi w środku alechciałbym po prostu móc z tego korzystać.
Teraz przejdę do problemu na jaki natrafiłem podczas testowania możliwości operatorów arytmetycznych wyrażeń lamba. Utworzyłem prostą klasę - complex z 3 składowymi int i zdefiniowanym operatorem +.
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
class complex
{
int a,b,c;
public:
complex(int a,int b,int c): a(a),b(b),c(c) {};
complex() {}
complex& operator=(const complex& arg);
friend complex operator+(const complex& c1,const complex& c2);
friend std::ostream& operator<<(std::ostream& os,const complex& c);
};
complex& complex::operator=(const complex& arg)
{
if(&arg!=this)
{
a=arg.a;
b=arg.b;
c=arg.c;
}
return *this;
}
complex operator+(const complex& c1,const complex& c2)
{
return complex(c1.a+c2.a,c1.b+c2.b,c1.c+c2.c);
}
std::ostream& operator<<(std::ostream& os,const complex& c)
{ os<<c.a<<" "<<c.b<<" "<<c.c<<" ";
return os;
}
int main() {
using namespace boost::lambda;
std::vector<complex> v1;
v1.push_back(complex(1,1,1));
v1.push_back(complex(1,1,1));
v1.push_back(complex(2,2,2));
v1.push_back(complex(3,3,3));
std::vector<complex> v2;
v2.push_back(complex(1,1,1));
v2.push_back(complex(1,2,3));
v2.push_back(complex(2,7,7));
v2.push_back(complex(3,8,9));
std::vector<complex> v3;
std::vector<std::string> s1;
s1.push_back(std::string("s1"));
s1.push_back(std::string("s2"));
std::vector<std::string> s2;
s2.push_back(std::string("s3"));
s2.push_back(std::string("s4"));
std::string s("string");
std::transform(s1.begin(),s1.end(),s2.begin(),s1.begin(),_1+"+"+_2);
std::for_each(s1.begin(),s1.end(),std::cout<<_1<<"\n");
std::transform(v1.begin(),v1.end(),v2.begin(),v1.begin(),_1+_2);
std::cin.get();
return 0;
}
Ze stringami nie ma żadnych problemów. Jest tworzony dwuargumentowy obiekt funkcyjny i wewnątzr niego jest dokonywane działanie string1+"+"+string2 po czym string wynikowy jest umieszczany w pierwszym z 2 przekazanych kontenerów.
Dlaczego to nie działa z obiektami mej klasy (complex) [???] . Zdefiniowałem dla niej operator + i chciałbym osiągnąć to samo co ze stringami czyli 2 complex-y sumujemy i wynikowy obiekt umieszczamy poprzez iterator wyjściowy w tym przypadku w pierwszym z 2 przekazanych kontenerów.
Przy próbie kompilacji dv-c++ sypie błędami min - no match for operator = i wiele innych,które mi nic nie mówią o tym gdzie tkwi problem(jak to zazwyczaj bywa z komunikatami o błędach zwłaszcza gdy ma my do czynienia z szablonami). Gdy usuniecie ostatnie wywołanie transform to program się skompiluje.