我用C ++包装类包装一些C遗留函数。我想做以下事情:
template<typename Function>
class NonVoidWrapper {
private:
Function func_;
public:
NonVoidWrapper(Function func) : func(func_) {}
template <typename... Args>
auto operator()(Args&&... args) -> decltype(func_(std::forward<Args>(args)...))
{
return func_(std::forward<Args>(args)...);
}
};
template<typename Function>
class VoidWrapper {
private:
Function func_;
public:
VoidWrapper(Function func) : func(func_) {}
template <typename... Args>
void operator()(Args&&... args)
{
func_(std::forward<Args>(args)...);
}
};
然后函数makeWrapper将返回一个基于函数返回类型的包装器对象,如下所示:
template<typename R, typename... Args>
struct ReturnType {
typedef R type;
};
template <typename Func>
auto makeWrap(Func f)
{
return std::conditional<std::is_void<typename ReturnType<decltype(f)>::type>::value, VoidWrapper<Func>, NonVoidWrapper<Func> >::type(f);
}
问题是上面的代码没有编译,因为返回类型取决于模板参数。我知道这很奇怪,如果函数重载可能不起作用,但是必须要这样做:)
我真的需要使用两个不同的包装器,如上所示,因为它们在
中做了稍微不同的事情T.C.建议的解决方案但是如何才能包含lambda函数(例如需要捕获参数但接受并返回void)?
A2:
我这样做 Q2 ,它只适用于返回无效的lambda
template<typename F>
struct FuncReturnType {
typedef void type;
};
template<typename R, typename... Args>
struct FuncReturnType<R (*)(Args...)>
{
typedef R type;
};
答案 0 :(得分:3)
无需区分void
和其他返回类型。例如,以下代码可以。
void f() {}
void g() { return f(); }
一般来说,根据cppreference:
在返回
void
的函数中,带有表达式的return语句 如果表达式类型为void
,则可以使用。
如果您想要推断出返回类型,请尝试使用std::result_of。