Hi Joel,
the question is what do I have to do to be able to use the following syntax instead _1 + llnorm(_2)
Lambdadoes not have such a facility. You can use Phoenix instead. Phoenix (lazy) functions allow you to do that. Phoenix is intended to supercedeLambda. Phoenix has been reviewed and is conditionally accepted into Boost after another mini-review.
Ok, I gave up with Boost.Lambda for defining such "lazy function" and used Phoenix instead. The process was quite painless. Below is the (working) code to define a lazy complex modulus function for those who are interested. I have still two concerns though: 1) I am worried how the lazy function can figure out which version of std::norm<T> to call to obtain the right result. For std::complex<double> the lazy function works fine (double is hard coded). But for std::complex<int> it seems that the lazy function will always convert the result to double, I couldn't make the lazy funcion as generic as the original std::norm<T>(std::complex<T> const& c) function. Is it possible to improve the lazy function definition in that respect? (BTW, for std::complex, T == std::complex<T>::value_type) (It is not that I think std::complex<int> is useful for something but I thing it is a good example to ask about this). 2) I may be asking for too much sugar but is there a way to name the function "std::norm" and not have conflicts with the standard "std::norm<T>(std::complex<T> const& c)", the best I could do was to call it std::norm_; The following is the working example, compares the Lambda version with the Phoenix version (sum5 and sum6): #include<vector> #include<iostream> #include<boost/lambda/lambda.hpp> #include<boost/lambda/bind.hpp> #include<boost/spirit/phoenix.hpp> #include<numeric> //for accumulate #include<complex> using std::cout; using std::endl; using std::complex; using std::vector; double sum_norm(double acc, complex<double> elem){ return acc+std::norm(elem); } namespace std{ struct norm_impl{ template <typename Arg> struct result{ typedef double type; }; template <typename Arg> typename result<Arg>::type operator()(Arg ar1) const{ return std::norm(ar1); } }; phoenix::function<norm_impl> norm_; } int main(){ //create data unsigned l=9; vector<complex<double> > v(l); for(int i=0; i!=v.size(); ++i) v[i]=std::complex<double>(i,1.2+i); // using manual loop over array double sum1=0; for(int i=0; i!=v.size(); ++i) sum1+=norm(v[i]); cout<<"sum1 = "<<sum1<<endl; // using manual loop over container double sum2=0; for(vector<complex<double> >::const_iterator it=v.begin(); it!=v.end (); ++it) sum2+=norm(*it); cout<<"sum2 = "<<sum2<<endl; //using automatic loop (accumulate) and free function double sum3=std::accumulate(v.begin(), v.end(), double(0), sum_norm); cout<<"sum3 = "<<sum3<<endl; //using accumulate and lambda with pure bind using namespace boost::lambda; double sum4=std::accumulate(v.begin(), v.end(), double(0), bind( std::plus<double>(), _1, bind(&std::norm<double>, _2) ) ); cout<<"sum4 = "<<sum4<<endl; //using accumulate and lambda double sum5=std::accumulate(v.begin(), v.end(), double(0), _1 + bind(&std::norm<double>,_2)); cout<<"sum5 = "<<sum5<<endl; // (cout << _1 << " = " << _2 << "\n") ("fancy print sum5", sum5); //using accumulate and phoenix using namespace phoenix; double sum6=std::accumulate(v.begin(), v.end(), double(0), arg1 + std::norm_(arg2) ); cout<<"sum6 = "<<sum6<<endl; return 0; }