简体   繁体   中英

Points to member variables and templating

I am currently using a templated function to evaluate the derivatives of mathematical functions, like so

template <class func_type>
arma::mat matrixDerivative
   (func_type func, const double x, double h, double b=1.4) {
      // <implementation details>
}

The template parameter allows me to use either function pointers or functors to evaluate the right-hand side.

Is there an easy way to extend this to evaluate the derivatives of functions that are class methods? I wasn't able to wrap my head around the use of function pointers to member functions and I couldn't work out the details of having a functor as a class attribute that still had access to its parent's attributes and methods.

My questions usually aren't clear, so feel free to ask for clarifications in the comments before answering.

In C++11 simply use a lambda:

[&]( double x )->double {
  return ptr->method(x);
}

which generates a function object that can be invoked with double . The above construct assumes that the lambda will be used and discarded before the end of the current scope ( [&] is unsafe otherwise).

Note that ->double can be omitted for single-line and void returning lambdas in C++11, and omitted even on multi-line lambdas in C++1y if you are ok with the return type it deduces (based off the first return statement in your function).

In C++03, std::mem_fun can be used, or you can create a custom function object.

In C++1y:

[&](auto&&... x) {
  return ptr->method(std::forward<decltype(x)>(x)...);/
}

creates a perfect-forwarding functor wrapper. I would rarely do that kind of thing, even in C++1y, outside of seriously industrial library code. Less verbose we get:

[&](auto&&... x) {
  return ptr->method(x...);
}

which lets us imperfectly forward, and defer selection of the overload to the point of use of the lambda, not the point where the lambda was written, which can be nice. (if any of the methods use rvalue or by-value calls, going back to perfect forwarding becomes tempting)

In C++11, std::mem_fn requires that the method in question not be overloaded, or that the overload be manually resolved (with an arcane-looking cast). std::bind then wraps that with a perfect-forwarding function object. The main advantage this procedure is is that the type of the construct, while implementation defined, can be determined, so you can have a function that returns the type in question. However, that is a pretty esoteric advantage: I would go with the lambda.

Lambdas, while strange, are increasingly common in C++, and are easier to understand what they are doing than a chain bind mem_fun expression in my experience as they look more like "normal" code (after you get over the "magic").

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM