我注意到函数指针类型的模板特化有几种不同的语法:
template<typename T>
struct Foo {};
template<typename R, typename... Args>
struct Foo<R (Args...)> {
static constexpr int value = 1;
};
template<typename R, typename... Args>
struct Foo<R (*)(Args...)> {
static constexpr int value = 2;
};
template<typename R, typename... Args>
struct Foo<R (&)(Args...)> {
static constexpr int value = 3;
};
int square(int x) { return x * x; }
Foo<decltype(square)>::value == 1; // true
Foo<decltype(&square)>::value == 2; // true
Foo<decltype(square)&>::value == 3; // true
甚至可能更多......?
我知道R (*)(Args...)
是一个很好的旧函数指针;我可以理解R (&)(Args...)
是对函数的引用,虽然它有点奇怪;但是R (Args...)
呢?我的猜测是该函数的 undecayed 类型。这是对的吗?
更新:评论中提到表单R(Args...)
是一个呼叫签名。现在问题变成:为什么decltype(some_plain_function)
与调用签名匹配而不是函数指针类型?这是否意味着未验明的函数类型 是一个调用签名?