[英]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.