std::is_invocable 是假的,但 std::invoke 有效

std::is_invocable is false but std::invoke works

本文关键字:std invoke 有效 is invocable      更新时间:2023-10-16

以下程序的输出似乎自相矛盾:

#include <type_traits>
#include <iostream>
#include <functional>
void foo(int&){ std::cout << "calledn"; }
int main() {
    int a;
    foo(a);
    std::cout << std::is_invocable_v<decltype(foo), decltype(a)> << std::endl;
    std::invoke(foo, a);
}

输出为:

called
0
called

在我看来,哪个是在调用一个不可调用的函数?这是怎么回事?

decltype(a) int 。这对应于使用 int prvalue 调用 f - 类似于 f(7) 。那个确实无法编译,因为非 const 的左值引用无法绑定到 prvalue 。

相反,你在main中所做的是用左值a调用f,引用可以很好地绑定到该值。

要从std::is_invocable获得正确的结果,请通过添加括号来使用 decltype 的表达式形式:

std::is_invocable_v<decltype(foo), decltype((a))>
//                                          ^ ^