[英]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 的文档建议它应该适用于Args
为void
(即无),特别是它说 void 情况不起作用是现在已弃用的std::result_of
的“怪癖”。
但是不, void
不起作用。 这是有道理的,因为人们也不能为T = void
做std::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.