C++11 函数包装器类型取决于包装器 return 类型
C++11 function wrapper type depending on wrappee return type
我正在用 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 将 return 一个基于函数 return 类型的包装器对象,如下所示:
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);
}
问题是上面的代码无法编译,因为 return 类型取决于模板参数。我知道这很奇怪,并且在函数过载的情况下可能无法工作,但是仍然必须这样做:)
备注
我确实需要使用如上所示的两个不同的包装器,因为它们在内部做的事情略有不同
Q2
T.C 建议的解决方案。有效,但是如何也包含 lambda 函数(需要捕获参数但接受 return void 例如)?
A2:
我这样做了 Q2,它只适用于 return void though
的 lambda
template<typename F>
struct FuncReturnType {
typedef void type;
};
template<typename R, typename... Args>
struct FuncReturnType<R (*)(Args...)>
{
typedef R type;
};
不需要区分void
和其他return类型。比如下面的代码就可以了
void f() {}
void g() { return f(); }
一般来说,根据cppreference:
In a function returning void
, the return statement with expression
can be used, if the expression type is void
.
如果你想推导出 return 类型,请尝试使用 std::result_of。
我正在用 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 将 return 一个基于函数 return 类型的包装器对象,如下所示:
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);
}
问题是上面的代码无法编译,因为 return 类型取决于模板参数。我知道这很奇怪,并且在函数过载的情况下可能无法工作,但是仍然必须这样做:)
备注
我确实需要使用如上所示的两个不同的包装器,因为它们在内部做的事情略有不同
Q2
T.C 建议的解决方案。有效,但是如何也包含 lambda 函数(需要捕获参数但接受 return void 例如)?
A2:
我这样做了 Q2,它只适用于 return void though
的 lambdatemplate<typename F>
struct FuncReturnType {
typedef void type;
};
template<typename R, typename... Args>
struct FuncReturnType<R (*)(Args...)>
{
typedef R type;
};
不需要区分void
和其他return类型。比如下面的代码就可以了
void f() {}
void g() { return f(); }
一般来说,根据cppreference:
In a function returning
void
, the return statement with expression can be used, if the expression type isvoid
.
如果你想推导出 return 类型,请尝试使用 std::result_of。