C++中template <R(*)(T)>含义及特定偏特化模板中*的作用解析
详解C++中的
template <R(*)(T)>与my_type模板 咱们一步一步拆解你问的这两个C++模板相关的问题,先从template <R(*)(T)>说起:
这是一个非类型模板参数的声明,简单说就是这个模板要接受一个函数指针作为参数。拆解一下细节:
R代表这个函数的返回类型,T是函数的参数类型;- 这里的
(*)是核心,用来明确这是个函数指针类型——要是你写成R*(T),编译器会把它解读成“返回值是R*、参数为T的函数”,完全不是我们要的意思。加了括号之后,就变成了“指向返回R、参数为T的函数的指针”,括号是用来改变运算符优先级的,缺一不可。
举个实际的例子:如果有个函数int foo(double),那template <int(*)(double)>这个模板就能接受&foo(或者直接写foo,因为函数名会隐式转成指针)作为参数。
接下来看你给出的my_type模板:
template <class R, class T> struct my_type<R(*)(T)> { typedef T type; };
这是一个模板偏特化,专门用来匹配“返回类型为R、参数为T的函数指针类型”。它的核心作用就是从给定的函数指针类型里,把参数的类型T给提取出来。
举个直观的使用例子:
// 先定义一个函数指针类型 using CalcFunc = int(*)(double); // 用my_type提取参数类型 typename my_type<CalcFunc>::type input; // input的类型就是double
这里CalcFunc是int(*)(double),my_type会匹配到这个偏特化版本,把内部的type定义成T也就是double。
最后说说这个上下文中的*到底是什么:
这里的*就是函数指针的标记,和你平时声明函数指针变量时的用法是一个逻辑——比如你写int(*fp)(double),这里的*表示fp是一个指向int(double)函数的指针。而在my_type的偏特化里,R(*)(T)是一个类型,用来告诉编译器:我们要匹配的是这种函数指针类型,然后把对应的R和T自动推导出来。
再给你整个可运行的代码例子,方便你理解:
#include <iostream> // 你的模板 template <class R, class T> struct my_type<R(*)(T)> { typedef T type; }; // 测试用的函数 float multiply(int num) { return num * 2.0f; } int main() { // 提取multiply的参数类型 my_type<decltype(&multiply)>::type value = 10; // value是int类型 std::cout << multiply(value) << std::endl; // 输出20.0 return 0; }
这里decltype(&multiply)得到的是float(*)(int)类型,my_type的偏特化会自动把R推导成float,T推导成int,所以type就是int。
内容的提问来源于stack exchange,提问作者Quasar




