How to implement the simplest C ++ called object wrapper?

I want to implement the FuncWrapper class, which behaves as shown below, but I believe that it is not as simple as expected.

int OrdinaryFunction(int n) { return n; } struct Functor { int operator ()(int n) { return n; } }; int main() { FuncWrapper<int(int)> f1(OrdinaryFunction); cout << f1(1); // output 1; Functor functor; FuncWrapper<int(int)> f2(functor); cout << f2(2); // output 2; return 0; } 

My question is: how to implement the FuncWrapper class in PURE C ++ (i.e. no STL) to compile the code?

I have a partially implemented FuncWrapper shown below:

 template<class T> class FuncWrapper; template<class ReturnType, class Parameter1> class FuncWrapper<ReturnType(Parameter1)> { public: typedef ReturnType (*FunctionPtr)(Parameter1); template<class Functor> FuncWrapper(Functor fn) { // ??? } FuncWrapper(FunctionPtr fn) : fn(fn) {} ReturnType operator ()(Parameter1 p1) { return this->fn(p1); } private: FunctionPtr fn; }; 
+4
source share
2 answers

Well, you might think that it’s just doing what you are trying to do, but it’s very difficult.

In your case, you want to be able to add a functor, as well as a real function, and this is what complicates the situation. After all, if your class takes a constructor to a Functor functor, where will you store the object?

One method used by boost in its generic pointer class for storing a deleter is to actually have a base class and a derived class. Your constructor will build an object (with a new one), which will be obtained from the base class, and then you will use polymorphism to call.

boost uses all kinds of smart methods in its function and the binder / mpl library, but for now I suggest you use this one.

If you are really against using boost or some kind of general pointer, you will have to manage memory for this object. (Annoying because you want your outer class to be available for copy and assignment.)

I am going to make it simple and say that I can use shared_ptr. I am also going to simplify the signature for now.

Like a circuit ...

 template< typename R, typename P > class FunctorBase { public: virtual ~FunctorBase() {} virtual R call(P p) = 0; }; template< typename R, typename P > class FunctionWrapper { shared_ptr< FunctorBase< R, P > > impl; public: template< typename F > // a functor FunctionWrapper( Functor f ) { // create appropriate impl for functors } FunctionWrapper( (R (func*)(P) ) { // create appropriate impl for functions } R operator()( P p ) { return impl->call(p); } }; 

Your functor implementation might look something like this:

 template< typename R, typename P, typename F > class FunctorImpl : public FunctorBase< R, P > { F f; public: FunctorImpl( F fparam ) : f( fparam ) { } R call( P p ) { return f( p ); } }; 

So now you see where you can save the functor.

+3
source

Just add a constructor to your functor that takes a pointer to a function (with the required function signature). Store the pointer in a functor and execute a pointed function from the operator ().

If you understand correctly, you need a shell that will expose the functional behavior to both functors and functions. Store a functor pointer in your wrapper instead of a function pointer. A constructor with a functor as a parameter will save the functor inside. The constructor with func as a pair will create a functor (as I wrote in the answer) and save it inside.

0
source

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


All Articles