假设我需要创建一个接受函数指针的类,存储它,然后运行它。我们还假设该类接受的函数可以返回void
或cReturnValue
;我的实际代码中还有其他要求和模板参数,与问题无关。
现在,如果返回类型为void
,我只需运行该函数即可。如果返回类型为cReturnValue
,我需要运行它,获取结果并使用它。是否可以在单个模板中处理这两种情况,而不使用部分特化?
template< typename Function, typename ReturnType > class Executor
{
public:
Executor(Function f) : _f(f) {}
void run()
{
//I know this will not work, but is this possible somehow?
if(std::is_same<ReturnType, void>::value)
{
_f();
}
else if(std::is_same<ReturnType, cReturnValue>::value)
{
cReturnValue val = _f();
//do some stuff with val
}
}
private:
Function _f;
};
答案 0 :(得分:6)
使用tag-dispatching:
template <typename> struct tag {};
template <typename Function, typename ReturnType>
class Executor
{
public:
Executor(Function f) : _f(f) {}
void run()
{
run(tag<ReturnType>{});
}
private:
void run(tag<cReturnValue>)
{
cReturnValue val = _f();
}
void run(tag<void>)
{
_f();
}
Function _f;
};
答案 1 :(得分:4)
我认为你不能用单一模板做这样的事情。但是你可以使用SFINAE。这样的事情是非常简单的方法:
private:
template<typename R>
typename std::enable_if<std::is_same<R, void>::value>::type run_()
{
_f();
}
template<typename R>
typename std::enable_if<!std::is_same<R, void>::value>::type run_()
{
ReturnType val = _f();
// do some stuff with val
}
并且运行将只是
void run()
{
run_<ReturnType>();
}