【问题标题】:Use invoke_result with void argument type?将 invoke_result 与 void 参数类型一起使用?
【发布时间】:2019-01-07 11:10:37
【问题描述】:

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

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 建议它应该适用于 Argsvoid(即无),特别是它表示无效案例不起作用是现已弃用的 std::result_of 的“怪癖”。

但是不,void 不起作用。这是有道理的,因为T = void 也不能使用std::declval&lt;T&gt;(),而std::invoke_result 应该按照std::declval 来实现。

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

相关问题:thisthis

【问题讨论】:

  • 可变参数模板?
  • 好叫,但不起作用。使用无参数调用 unwrap() 不是问题,只是 invoke_result_t 不起作用
  • “与 void 一起工作”是什么意思? Unwrapper 不能用void 类型的对象调用(因为没有void 类型的对象),所以invoke_result 可以说是在做它应该在这里做的事情。
  • @cpplearner void 是一种类型,不是完全的(如创建和传递对象 of it),但在某些程度上是的,例如你可以使用return void() 语法与模板保持一致。我相信void 也是一种类型,你可以问“返回 void 的方法的返回类型是什么”。答案是“它是void”。
  • 好吧,如果你使用std::invoke_result_t&lt;Unwrapper&gt;,你会得到void,但std::invoke_result_t&lt;Unwrapper, void&gt;不存在,因为void不能作为参数。

标签: c++ c++17 void result-of declval


【解决方案1】:

你可以这样做:

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

UnwrappedT&lt;&gt; 将处理 void 的情况。

如果您希望 UnwrappedT&lt;void&gt; 表示 UnwrappedT&lt;&gt;,则需要某种方式删除 voidconditional 是最熟悉的做法:

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>>;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-03
    • 2014-04-20
    • 1970-01-01
    • 2011-10-19
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多