void f(int) 的模板和声明类型

Grz*_*orz 3 c++ templates traits decltype c++11

我正在学习仅使用 C++11 借用std::true_typestd::false_type.

我创建了以下特征:

#include <iostream>

template <typename F>
struct is_farg1: std::false_type {};

template <typename R, typename A>
struct is_farg1<R (*)(A)> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)

现在考虑一个包含上述特征的程序,以及以下代码:

void f(int) {}

int main() {
    std::cout << "is_farg1<decltype(f)>  : " << is_farg1<decltype(f)>::value << std::endl;
    std::cout << "is_farg1<void(*)(int)> : " << is_farg1<void(*)(int)>::value << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它产生以下输出:

is_farg1<decltype(f)>  : 0
is_farg1<void(*)(int)> : 1
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 为什么is_farg1<void(*)(int)>::valuetrue同时is_farg1<decltype(f)>::value返回false
  2. 如果我的 trait 写错了,那么我如何检查给定的函数是否只有一个参数,以便我也可以使用decltype(f)

son*_*yao 6

因为decltype(f)给出了确切的函数类型(即void(int))而不是函数指针类型(即void(*)(int))。当decltype用于实体时,

如果参数是无括号的id 表达式或无括号的类成员访问表达式,则decltype生成由此表达式命名的实体的类型。

您可以为函数类型添加另一个特化,如

template <typename R, typename A>
struct is_farg1<R (A)> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)

居住

或者检查类型作为函数指针

is_farg1<decltype(f)*>::value
//                  ^

// or
is_farg1<decltype(&f)>::value
//                ^
Run Code Online (Sandbox Code Playgroud)

居住