Functional shell through (functional object) class (variational) template

C ++

I am trying to implement a function wrapper through a template (object object) class (variadic). A class has as its only data element a function pointer that is initialized or assigned by the function pointer that it wraps. A parameterized constructor takes a function pointer and initializes its element. The operator() method takes arguments (or none) and calls a wrapped function with them. At least this idea. I get a lot of errors that I comment on. VC11 (from November 2012 CTP to enable variable templates) gives me error C2091: function returns function in all but one of the marked areas. The last error is different, and I comment on its full description in the code. g ++ gives basically the same errors, albeit with different code numbers.

 #include <iostream> template <typename R, typename... Tn> class func { R (*fptr)(Tn...); // C2091 public: func() : fptr(nullptr) {} func( R (*f) (Tn...) ) : fptr(f) {} // C2091 R operator()(Tn... args) { // C2091 return fptr(args...); } func& operator=( R (*f) (Tn...) ) // C2091 { fptr = f; return *this; } }; int foo(int a, int b) { std::cout << "foo\n"; return 0; } int main() { func<int(int, int)> myfunc; myfunc = foo; // C2679: binary '=' : no operator found which takes // a right-hand operand of type 'int (__cdecl *)(int,int)' (or // there is no acceptable conversion) } 

Why am I getting these errors? For example, I don’t see how a parameterized constructor returns something or how a declaration of a data element returns something. Isn't that a data declaration declaration in the form of a function pointer declaration? For example, not int (*g)(int); declares a pointer pointing to a function that takes an int and returns an int ?

Edit / Add:

From the answers, I see that int(int, int) is only one type, and I need a partial specialization to get the effect I want. But what causes the error in my code? If I comment on myfunc = foo , I still get other errors. func<int(int, int)> myfunc; calls the default constructor. typename R gets an instance of int(int, int) , and typename... Tn becomes empty. Data element R (*fptr)(Tn...); becomes R (*fptr)(); , and fptr is thus a function pointer that points to a function that takes zero arguments and returns R If R int(int, int) , that is, R type of the function pointer or the type of the function? If this is the last, then I can understand the context of the error message.

+1
c ++ functor function-object function-pointers variadic-templates
source share
3 answers

int(int, int) is one type. If you want to convey this and expand it, you will need a partial specialization:

 template <typename> struct func; // leave undefined template <typename R, typename ...Args> struct func<R(Args...)> // specialized for typename = R(Args...) { // ... }; 
+2
source share

Your class is parameterized by the return value and argument types, which are specified separately. But when creating an instance, you try to parameterize it using the function type a la std::function . Make it func<int, int, int> myfunc; . Your code works with this change.

+2
source share

You need a partial specialization.

Here is a working example:

 template <typename T> class func; template <typename R, typename... Tn> class func<R(Tn...)> { typedef R (*fptr_t)(Tn...); fptr_t fptr; public: func() : fptr(nullptr) {} func(fptr_t f) : fptr(f) {} R operator()(Tn... args) { return fptr(args...); } func& operator=(fptr_t f) { fptr = f; return *this; } }; 
+2
source share

All Articles