is_invocable_r忽略返回参数

时间:2019-07-13 12:25:48

标签: c++ templates c++17

在评论有关std::conjunction没有短路(Conjuction template doesn't short circuit)的问题时,建议我std::is_invocable_r作为解决我那里问题的方法。但是,当我尝试使用它时,我发现了一些非常奇怪的行为。例如,此代码使两个断言均失败:

#include <type_traits>

int main()
{
    static_assert(!std::is_invocable_r_v<void, int(int), int>);
    static_assert(std::is_convertible_v<int,void>);
    return 0;
}

请注意cppreferenceis_invocable_r的描述:

  

确定是否可以使用参数Fn调用ArgTypes...以产生可转换为R的结果。

很明显int无法转换为void,第二个断言确认了这一点。问题是为什么std::is_invocable_r_v<void, int(int), int>会产生一个true的值。这是一个实时示例:https://godbolt.org/z/HywH7D

请注意,您可以使用std::is_void_v<std::invoke_result_t<int(int),int>>在此处(https://godbolt.org/z/YMvc47)获得正确答案,但这不是我的问题。 (而且不能从合取题中解决我的问题)。

1 个答案:

答案 0 :(得分:2)

紧接着

  

确定是否可以使用参数Fn调用ArgTypes...以产生可转换为R的结果。 ...

它给出了更严格的定义:

  

...形式上,确定INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...)的格式是否正确,其中INVOKE Callable 中定义的操作>

Callable 中,解释了INVOKE<void>是特例。

不是将返回值隐式转换为R,而是使用static_cast<void>(...)(适用于任何返回类型的格式)。