Avoid explicit template pattern

I play with functors. I use the standard example below:

class C { public: template <typename Func> void foo(Func fun) { fun(); } }; struct S { void operator()() { printf ("in S\n"); } }; .... C myClass; myClass.foo (S()); 

This works well, and I don't need to explicitly specify the type of the S template in the call to foo (), it just shows it. But suppose I want to save the functor as a member variable and call it later:

 class C { public: template <typename Func> void foo(Func fun) { _myFunc = fun; } void someOtherThing() { _myFunc(); } private: WHAT_IS_THIS_TYPE _myFunc; }; 

Now I need to make the whole class a template? If so, can the compiler infer the type of the template in the same way as with a single functor, or should I explicitly provide it? Thanks.

+4
source share
2 answers

You can use std :: function (in C ++ 11) or boost :: function to store called objects (functions, functors). It implements a pattern erase type.

 class C { public: template <typename Func> void foo(Func fun) { _myFunc = fun; } void someOtherThing() { _myFunc(); } private: std::function<void()> _myFunc; }; 
+4
source

Here's a manual way to avoid creating a class C template:

 struct C { template <typename Func> void foo(Func fun) { _myFunc = static_cast <void*>(&fun); stub = call <Func>; } void someOtherThing() { stub(_myFunc); } private: void* _myFunc; void (*stub)(void*); template <typename F> static void call(void* f) { (*static_cast <F*>(f))(); } }; struct S { void operator()() { std::cout << "in S" << std::endl; } }; int main() { S s; C myClass; myClass.foo(s); myClass.someOtherThing(); } 

When you call foo() , the Func type is "stored" inside the static function of the call template, a pointer to (instatiation of), which is stored in stub . The latter is called by someOtherThing to actually call _myFunc , which is nothing more than a simple void* . To make this happen, _myFunc first returns to the correct type, which is known only inside the call body.

The only catch is that using function pointers there cannot be an insert to call stub(...) .

-one
source

Source: https://habr.com/ru/post/1502788/


All Articles