Kap*_*ade 1 c++ templates function 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");
Run Code Online (Sandbox Code Playgroud)
可以看出,非void和void类型需要单独的模板,因为在null的情况下,如果函数指针为NULL,则不应返回任何内容.如何规避这个问题并为两者制作一个单独的模板?
你可以return T();(假设T是你想要的返回类型).这适用于void类型.它不适用于具有非默认构造函数的类型.
#include <iostream>
#include <utility>
void foo() {
std::cout << "void foo()\n";
}
int bar(int u, char* c_str) {
std::cout << "int bar(" << u << ", \"" << c_str << "\")\n";
return u;
}
template<typename T>
class WrapFuncObj;
template<typename T, typename... Args>
class WrapFuncObj<T(Args...)> {
T (*f)(Args...);
public:
WrapFuncObj(T (*t)(Args...)) {
f = t;
}
T operator()(Args&&... args) {
if(f != nullptr) {
return (*f)(std::forward<Args>(args)...);
} else {
return T();
}
}
};
int main() {
WrapFuncObj<void()> wrap_foo(&foo);
wrap_foo();
WrapFuncObj<int(int, char*)> wrap_bar(&bar);
wrap_bar(0, "test");
WrapFuncObj<void()> wrap_null(nullptr);
wrap_null(); // prints nothing.
}
Run Code Online (Sandbox Code Playgroud)
现场演示.
我觉得有必要建议std::function,这是你要重新发明的东西(除非你允许调用一个null函数并返回一个默认类型,这可能是你真正想做的事情,也可能不是.)