c++ 如何定义可以处理 R 的 std::result_of<F(R)> 是无效的

标签 c++ c++11 templates variadic-templates result-of

当我使用

std::result_of<F(R)>

像这样:

template<typename R, typename... Args>
class Task
{
    //...

    template<typename F>
    auto Then(F&& f) -> Task<typename std::result_of<F(R)>::type(Args...)>
    {  
        //... 
    }    
}; 

由于R是另一个函数的输出类型,所以R可能是void,在这种情况下,会有:

error: invalid parameter type ‘void’.

所以问题是如何处理 Rvoid 和不是?

最佳答案

选项 #1

基于 SFINAE:

template <typename F>
class Task;

template <typename R, typename... Args>
class Task<R(Args...)>
{
public:
    template <typename F, typename Ret = R>
    auto Then(F&& f)
        -> typename std::enable_if<!std::is_void<Ret>::value, Task<typename std::result_of<F(Ret)>::type(Args...)>>::type
    {
        return {};
    }

    template <typename F, typename Ret = R>
    auto Then(F&& f)
        -> typename std::enable_if<std::is_void<Ret>::value, Task<typename std::result_of<F()>::type(Args...)>>::type
    {
        return {};
    }
};

DEMO

选项 #2

类模板的部分特化:

template <typename F>
class Task;

template <typename R, typename... Args>
class Task<R(Args...)>
{
public:
    template <typename F>
    auto Then(F&& f)
        -> Task<typename std::result_of<F(R)>::type(Args...)>
    {
        return {};
    }
};

template <typename... Args>
class Task<void(Args...)>
{
public:
    template <typename F>
    auto Then(F&& f)
        -> Task<typename std::result_of<F()>::type(Args...)>
    {
        return {};
    }
};

DEMO 2

选项 #3

标签分发:

template <typename F>
class Task;

template <typename R, typename... Args>
class Task<R(Args...)>
{    
private:
    template <typename F>
    auto ThenImpl(F&& f, std::true_type)
        -> Task<typename std::result_of<F()>::type(Args...)>
    {
        return {};
    }

    template <typename F, typename Ret = R>
    auto ThenImpl(F&& f, std::false_type)
        -> Task<typename std::result_of<F(Ret)>::type(Args...)>
    {
        return {};
    }

public:
    template <typename F>
    auto Then(F&& f)
        -> decltype(ThenImpl(std::forward<F>(f), std::is_void<R>{}))
    {
        return ThenImpl(std::forward<F>(f), std::is_void<R>{});
    }
};

DEMO 3

关于c++ 如何定义可以处理 R 的 std::result_of<F(R)> 是无效的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52253620/

相关文章:

c++ - MFC 功能区主页按钮双击关闭应用程序

c++ - 如何使用带有引用的函数指针创建 std::thread ?

c++ - 为什么模板非类型参数指针和引用参数需要是全局的

c++ - 模板函数中的条件代码生成

c++ - 如何从另一个类获取std::bitset的大小?

C++11 只允许继承某些类

c++ - 复制和赋值构造函数的问题

c++ - vector 调整大小奇怪的行为

c++ - shared_ptr<T>::get() 释放后的返回值是多少?

c++ - 错误 : ‘template<class> class std::auto_ptr’ is deprecated