I do not want to say that I cannot understand this, but I cannot understand this. I googled and searched for Stack Overflow, and came up with an empty one.
An abstract and perhaps too vague form of the question: how can I use a feature template to create member elements? [Update: I used the wrong term here. These should be “politicians,” not “traits.” Traits describe existing classes. Politicians prescribe synthetic classes.] The question arose when modernizing the set of optimizers for multidimensional functions that I wrote more than 10 years ago.
All optimizers work by choosing a straight path through the parameter space away from the current best point ("update"), then I find a more accurate point in this line ("line search"), and then testing for the condition "done", and if it is not done , iteration.
There are various methods for performing an update, finding a line, and possibly for a test done and other things. Mix and match. Different update formulas require different state variable data. For example, a vector is required to update LMQN, and a matrix is required to update BFGS. If evaluating gradients is cheap, a line lookup should do it. If not, he should use only evaluation functions. Some methods require more accurate line searches than others. These are just a few examples.
The original version creates several combinations using virtual functions. Some features are selected by setting the mode bits, which are tested at runtime. Ugh. It would be trivial to define C # define features and member functions using #ifdef and macros. But this is so twenty years ago. It seems to me that I can’t understand which one was taken in a modern way.
If only one trait changed, I could use a curiously repeating pattern template. But I do not see the possibility of extending this to arbitrary combinations of signs.
I tried to do this with boost::enable_if etc. Specialized status information was simple. I managed to execute these functions, but only resorting to external external functions that have the this -pointer parameter as a parameter. I did not even understand how to make functions friends, and even more so as member functions. The compiler (VC ++ 2008) always complained that things did not match. I would shout: "SPHINIA, you moron!" but the moron is probably me.
Perhaps the send tag is the key. I did not understand this very deeply.
Of course, this is possible, right? If so, what is the best practice?
UPDATE: Here is another attempt to explain this. I want the user to be able to fill out an order (manifest) for a custom optimizer, something like sorting a Chinese menu - one from column A, one from column B, etc. Waiter from column A (updates), I will have a BFGS update with Cholesky-decpositon sauce. From column B (search lines) I will have a cubic interpolation line search with a sort of 0.4 and rho 1e-4, please. Etc ...
UPDATE: Alright, alright. Here is the game I made. I suggest this reluctantly because I suspect that this is a completely wrong approach. It works fine in vC ++ 2008.
#include <boost/utility.hpp> #include <boost/type_traits/integral_constant.hpp> namespace dj { struct CBFGS { void bar() {printf("CBFGS::bar %d\n", data);} CBFGS(): data(1234){} int data; }; template<class T> struct is_CBFGS: boost::false_type{}; template<> struct is_CBFGS<CBFGS>: boost::true_type{}; struct LMQN {LMQN(): data(54.321){} void bar() {printf("LMQN::bar %lf\n", data);} double data; }; template<class T> struct is_LMQN: boost::false_type{}; template<> struct is_LMQN<LMQN> : boost::true_type{}; // "Order form" struct default_optimizer_traits { typedef CBFGS update_type; // Selection from column A - updaters }; template<class traits> class Optimizer; template<class traits> void foo(typename boost::enable_if<is_LMQN<typename traits::update_type>, Optimizer<traits> >::type& self) { printf(" LMQN %lf\n", self.data); } template<class traits> void foo(typename boost::enable_if<is_CBFGS<typename traits::update_type>, Optimizer<traits> >::type& self) { printf("CBFGS %d\n", self.data); } template<class traits = default_optimizer_traits> class Optimizer{ friend typename traits::update_type; //friend void dj::foo<traits>(typename Optimizer<traits> & self); // How? public: //void foo(void); // How??? void foo() { dj::foo<traits>(*this); } void bar() { data.bar(); } //protected: // How? typedef typename traits::update_type update_type; update_type data; }; } // namespace dj int main() { dj::Optimizer<> opt; opt.foo(); opt.bar(); std::getchar(); return 0; }