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