[英]C++ function template specialization and overloading
考虑以下代码:
template <class T>
void f(T p) { //(1)
cout << "Second" << endl;
}
template <>
void f(int *p) { //(2)
cout << "Third" << endl;
}
template <class T>
void f(T* p) { //(3)
cout << "First" << endl;
}
诸如int *p; f(p);
类的调用int *p; f(p);
int *p; f(p);
将输出First
。
如果声明的顺序更改,则如下所示:
template <class T>
void f(T* p) { //(3)
cout << "First" << endl;
}
template <class T>
void f(T p) { //(1)
cout << "Second" << endl;
}
template <>
void f(int *p) { //(2)
cout << "Third" << endl;
}
相同的调用( int *p; f(p);
)将输出Third
。
我了解了函数模板重载解析的发生方式:首先,该解析仅考虑非模板函数和基础模板 。 选择“最专业的”后,如果它是模板函数,并且对推导(或明确指定)的参数具有专业化,则调用该专业化。
现在我的问题是:如何确定函数对哪个基础模板是专业化的? 在我的示例中,(2)对哪个函数模板重载((1)或(3))有专长?
我的猜测是,在声明专业化时,将考虑已经声明的模板,然后从模板中选择最“专业化”(其参数与该专业化“最接近”)。 这个对吗? 另外,您能指出我在标准中指定的地方吗?
它打印“ First”,因为声明的顺序会影响您实际上专门研究的模板。
您的示例有两个函数模板,它们重载了相同的名称。 在第一种情况下,您专门研究void f(T p)
,因为它是到目前为止唯一可见的模板。
在第二种情况下,专用的void f(T* p)
。 是的,您的猜测是正确的。 详细信息在[temp.deduct.decl / 1] :
在声明符的声明者ID表示函数模板的特化的声明中,执行模板参数推导来标识声明所引用的特化 。 具体来说,这是为显式实例化, 显式专业化和某些朋友声明完成的。 [...]
包括功能模板的部分排序。 但是,部分排序仅在您引入专业化时才适用于可用的函数模板声明。
标准在[temp.expl.spec / 7]发出警告:
函数模板的显式专业化声明的位置 , 会根据上面和下面所指定的显式专业化声明的相对位置及其在翻译单元中的实例化点,影响程序是否格式正确。 编写专长时,请注意其位置; 或使其编译将是点燃其自焚的审判。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.