c++ - Design pattern for static base constructor that calls static method in final class -


how can achieve following design using c++11:

class consumer : base<consumer> {     // different consumers have different methods (of same signature)     void foo(){...}     void bar(){...}     : // etc.      static void override     register_all () {         register_method<&consumer::foo>("foo");         register_method<&consumer::bar>("bar");         : // etc.     }     : }  template<typename t> class base {     static      base() {          register();      }      virtual static void     register_all(){ };      using f = void(t::*)();      template<f f>     static void      register_method(std::string name) {         ...     } } 

...?

note i'm doing 2 illegal things:

  • i using static constructor (not allowed) on base class
  • i using virtual static function (also not allowed)

note: registration of methods needs occur once, before first instance accessed (it populate static c-function-pointer table).

finally, there better technique using, way of somehow tagging or marking methods need registered, , save consumer trouble of having manually register them in separate function?

i believe regular crtp work fine. gets rid of both virtual , static. using std::once_flag in combination std::call_once allow call function once -- mimicking effects of 'static constructor'. requires little bit of messing around.

full code:

#include <iostream> #include <mutex>  template<typename t> struct base {     base() {         static_cast<t*>(this)->register_all();     }      using f = void(t::*)();      template<f f>     void register_method(const char* str) {         // ...         std::cout << "registered " << str << '\n';     } };  struct derived : base<derived> { private:     static std::once_flag flag_;     void implementation() {         register_method<&derived::foo>("foo");         register_method<&derived::bar>("bar");     } public:     void foo() {}     void bar() {}      void register_all() {         std::call_once(flag_, [this]{ implementation(); });     } };  std::once_flag derived::flag_;  int main() {     derived x;     derived y; } 

live demo


Comments

Popular posts from this blog

c++ - QTextObjectInterface with Qml TextEdit (QQuickTextEdit) -

javascript - angular ng-required radio button not toggling required off in firefox 33, OK in chrome -

xcode - Swift Playground - Files are not readable -