c++ - 为什么 std::is_invocable, 标准::decay_t>::值是假的?
问题描述
std::is_invocable<std::decay_t<void(int&)>, std::decay_t<int>>::value
评估为假。
但
void(int&)
衰减到
void*(int&)
并
int
_
int
我可以std::invoke
这样使用:
void f(int&);
...
auto* fp = f;
int i = 0;
std::invoke(fp, i);
当我查看std::thread
构造函数时,我碰到了这个:
template<typename _Callable, typename... _Args,
typename = _Require<__not_same<_Callable>>>
explicit
thread(_Callable&& __f, _Args&&... __args)
{
static_assert( __is_invocable<typename decay<_Callable>::type,
typename decay<_Args>::type...>::value,
"std::thread arguments must be invocable after conversion to rvalues"
);
我理解为什么不鼓励传递对std::thread
构造函数的引用(我们仍然可以使用std::ref()
),但我不明白为什么void *(int&)
不能用int
.
解决方案
std::is_invocable<..., int>
尝试使用int
右值作为参数。它相当于std::is_invocable<..., int &&>
.
使用std::is_invocable<..., int &>
.
...形式上,确定是否
INVOKE(declval<Fn>(), declval<ArgTypes>()...)
形成良好...
即使我们忽略什么INVOKE
,您也可以看到它is_invocable
是使用 定义的std::declval<ArgType>()
,它返回ArgType &&
。
ArgType &&
嗯,是一个右值引用。除非ArgType
是左值引用,在这种情况下ArgType &&
等价于ArgType
并且是左值引用(根据引用折叠规则)。