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; }
Comments
Post a Comment