是否可以使用NULL检查制作通用C ++函数指针包装器?

时间:2016-07-02 21:30:45

标签: c++ function templates wrapper generic-programming

我必须包含几个可以具有NULL值的函数指针。我正在尝试为此创建一个通用类模板,它检查函数指针是否为NULL,如果指针不为NULL则调用原始函数,如果指针为NULL则返回默认值。像这样:

//Function typedefs
typedef void(*foo)();
typedef int(*bar)(int u, char *);

//Function pointers
foo gfFoo;
bar gfBar;

//Wrapper class
template<typename T,  typename... Args>
class WrapFuncObj {
    T* f;
public:
    WrapFuncObj(T* t) {
        f = t;
    }
    typename std::result_of<T(Args...)>::type operator()(Args&&... args) {
        if(f != nullptr){
            return (*f)(std::forward<Args>(args)...);
        }
        else
        {
            return 0; //RETURN something for non-void types
        }
    }
};

template<typename T,  typename... Args>
class WrapFuncObjVoid {
    T* f;
public:
    WrapFuncObjVoid(T* t) {
        f = t;
    }
    typename std::result_of<T(Args...)>::type operator()(Args&&... args) {
        if(f != nullptr){
            (*f)(std::forward<Args>(args)...);
        }
        else
        {
            //DO Nothing for void 
        }
    }
};

//Usage:
WrapFuncObjVoid<foo> WrapFoo(&gfFoo);
WrapFoo();
WrapFuncObj<bar, int, char*> WrapBar(&gfBar); 
WrapBar(0, "test");

可以看出,对于非void和void类型需要单独的模板,因为在null的情况下,如果函数指针为NULL,则不应返回任何内容。如何规避这个问题并为两者制作一个足够的模板?

1 个答案:

答案 0 :(得分:5)

您可以#include <stdio.h> #include <stdlib.h> int n; struct point{ int x,y; }; typedef struct point Point; void resize(Point*xy) { xy=(Point*)realloc(xy,sizeof(Point)); for (n=0;n<4;n++) { xy[n].x=n; xy[n].y=n; } } int main () { Point *xy; xy=(Point*)malloc(2*sizeof(Point)); for (n=0;n<2;n++){ xy[n].x=n; xy[n].y=n; } resize(xy) ; for (n = 0; n<4; n++) { printf("xy[%i].x= %i \n",n,xy[n].x); printf("xy[%i].y= %i \n",n,xy[n].y); } free(xy); return 0; } (假设return T();是您想要的返回类型)。这适用于T类型。它不适用于具有非默认构造函数的类型。

void

Live demo

我觉得有必要建议std::function,这是您尝试重新发明的内容(除非您允许调用null函数并返回默认类型,这可能是也可能不是您真正想要的内容做)。