繁体   English   中英

将 invoke_result 与 void 参数类型一起使用?

[英]Use invoke_result with void argument type?

我正在尝试执行以下操作:

struct Unwrapper
{
    template<typename T>
    auto operator()(const T& arg, std::enable_if_t<isPrimitive<T>, void>* = nullptr) {return arg;}

    template<typename T>
    auto operator()(const T& arg, std::enable_if_t<!isPrimitive<T>, void>* = nullptr) {return arg.wrapped();}

    void operator()(void) {}
};

template<typename T>
using UnwrappedT = std::invoke_result_t<Unwrapper, T>; // error: no type named ‘type’ in ‘struct std::invoke_result<Unwrapper, void>’

std::invoke_result 的文档建议它应该适用于Argsvoid (即无),特别是它说 void 情况不起作用是现在已弃用的std::result_of的“怪癖”。

但是不, void不起作用。 这是有道理的,因为人们也不能为T = voidstd::declval<T>() ,并且std::invoke_result应该根据std::declval来实现。

问题是,修补代码以使用 void 的最优雅/直接的方法是什么? 我可以用std::conditional做点什么,但我期望更好。 (使用 C++17)

相关问题: 这个这个

你可以这样做:

template<typename... T>
using UnwrappedT = std::invoke_result_t<Unwrapper, T...>; 

UnwrappedT<>将处理void情况。

如果您希望UnwrappedT<void>表示UnwrappedT<> ,则需要某种方法来删除void conditional是最熟悉的方式:

template<typename T>
using UnwrappedT = typename std::conditional_t<
    std::is_void_v<T>,
    std::invoke_result<Unwrapper>,
    std::invoke_result<Unwrapper, T>>::type;

或者你可以在 Boost.Mp11 中获得一些乐趣:

template<typename T>
using UnwrappedT = mp_apply<std::invoke_result_t,
    mp_remove_if<mp_list<Unwrapper, T>, std::is_void>>;

你有没有尝试过?

template<typename T>
using UnwrappedT = std::result_of_t<Unwrapper(const T&)>;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM