C ++ 11函数包装器类型取决于wrappee返回类型

时间:2015-04-09 11:09:53

标签: c++11 metaprogramming

我用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);
}

问题是上面的代码没有编译,因为返回类型取决于模板参数。我知道这很奇怪,如果函数重载可能不起作用,但是必须要这样做:)

注意

我真的需要使用两个不同的包装器,如上所示,因为它们在

中做了稍微不同的事情

Q2

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;
};

1 个答案:

答案 0 :(得分:3)

无需区分void和其他返回类型。例如,以下代码可以。

void f() {}
void g() { return f(); }

一般来说,根据cppreference

  

在返回void的函数中,带有表达式的return语句   如果表达式类型为void,则可以使用。

如果您想要推断出返回类型,请尝试使用std::result_of