将 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>’
docs for std::invoke_result 表明它应该适用于 Args
为 void
(即 none),具体来说它说 void 情况不起作用是 "quirk" 现已弃用 std::result_of
.
但是不,void
不起作用。这是有道理的,因为 std::declval<T>()
也不能为 T = void
做,而 std::invoke_result
应该根据 std::declval
.
来实现
问题是,最elegant/direct 修补代码以使用 void 的方法是什么?我可以用 std::conditional
做点什么,但我期望更好。
(使用 C++17)
相关问题:, this.
你可以这样做:
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>>;
我正在尝试执行以下操作:
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>’
docs for std::invoke_result 表明它应该适用于 Args
为 void
(即 none),具体来说它说 void 情况不起作用是 "quirk" 现已弃用 std::result_of
.
但是不,void
不起作用。这是有道理的,因为 std::declval<T>()
也不能为 T = void
做,而 std::invoke_result
应该根据 std::declval
.
问题是,最elegant/direct 修补代码以使用 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>>;