Hi Roland, you wrote:
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express this more concise.)
I hope, we'll be able to solve this, too.
Finally I found a solution that works with expressions, without the burden of template parameter specification. I took up your suggestion and blended it with boost::function. I would be glad if you could have a look on it and perhaps comment. ==================================================================== #include <iostream> #include
#include #include #include #include using namespace boost::numeric::ublas; // this is the class that implements the functor // it also could be parameterized on more than one expression // (this is what Joerg suggested) template
class func_impl { public: func_impl(const vector_expression<E> &e) : e_ (e) {}
func_impl(const vector_expression<E> &e) : e_ (e ()) {}
T operator() (const T& x){ // algorithm goes here ... return e_()(0)*x; // just for demonstration } private: const vector_expression<E> &e_;
// Storing the closure type should prevent some subtle lifetime issues // when chaining functions for example... typename E::const_closure_type e_;
};
// this is the user part of the functor // the constructor is used to act as a generator for the // implementation type. template<class T> class func : public boost::function1
{ public: template<class E> func(const vector_expression<E>& e) : boost::function1 (func_impl (e)) {} }; int main(int argc, char* argv[]) { matrix<double> m (3,3); vector<double> v (3); func<double> f(m.row(0)); // notice: no need to know the type of m.row
m(0,0) = 0.0; m(0,1) = 0.1; m(0,2) = 0.2; m(1,0) = 1.0; m(1,1) = 1.1; m(1,2) = 1.2; m(2,0) = 2.0; m(2,1) = 2.1; m(2,2) = 2.2;
std::cout << f(1.0) << std::endl; // outputs: 0
m(0,0) = 47.11; // change the referenced matrix std::cout << f(1.0) << std::endl; // outputs: 47.11
// other argument types ... func<double> f1(m.column(2)); std::cout << f1(1.0) << std::endl; // outputs: 0.2 m(0,2) = 13; std::cout << f1(1.0) << std::endl; // outputs: 13
// similar with vector ... func<double> f2(v);
return 0; } ====================================================================
Of course this involves an indirection since I am using the functiom.hpp from boost as base class. But I think this is not avoidable in principle, since this is what a reference is all about, isn't it?
Impressed-by-this-nice-combination-of-different-libraries-ly y'rs Joerg