wor*_*tor 5 c++ templates overloading
以下是两个模板函数,它们的模板参数不同.其余参数完全相同.
template<int module>
void template_const(int &a,int & b){
a = a & module;
b = b % module;
}
template<bool x>
void template_const(int &a,int & b){
int w;
if (x){
w = 123;
}
else w = 512;
a = a & w;
b = b % w;
}
Run Code Online (Sandbox Code Playgroud)
当我试图像这样打电话给他们
template_const<true>(a,b)
Run Code Online (Sandbox Code Playgroud)
要么
template_const<123>(a,b)
Run Code Online (Sandbox Code Playgroud)
编译器告诉我调用是不明确的.我怎么称呼这两个功能?
正如@jogojapan指出的那样,问题在于编译器无法对这两个函数进行排序,即没有一个比另一个更专业.如§14.5.6.2中所述,当对重载函数模板的调用不明确时,编译器使用各种重载之间的部分排序来选择最专用的模板.
为了对重载进行排序,编译器会转换它们中的每一个并执行模板参数推导,以查看一个是否比另一个更专业(在本答案的末尾有一个简短的解释).在您的情况下,两个重载是等效的(或不可比较):template<int> void template_const(int &,int &)不是更专业template<bool> void template_const(int &, int &),反之亦然.
因此,编译器不能选择其中一个,因此会产生ambiguous call错误.
如果您可以明确指定要传递的参数类型,则可以使用部分模板特化,如下所示:
template<typename T, T param>
struct template_const_impl;
template <int module>
struct template_const_impl<int, module>
{
static void apply(int &a, int &b)
{
a = a & module;
b = b % module;
}
};
template<bool x>
struct template_const_impl<bool, x>
{
static void apply(int &a, int &b)
{
const int w = x ? 123 : 512;
a = a & w;
b = b % w;
}
};
template <typename T, T param>
void template_const(int &a, int &b)
{
return template_const_impl<T, param>::apply(a, b);
}
int main()
{
int i = 512, j = 256;
template_const<int, 123>(i, j);
template_const<bool, true>(i, j);
}
Run Code Online (Sandbox Code Playgroud)
这并不理想,但除非你能使用C++ 11并且愿意依赖某些宏,否则它认为没有更清晰的解决方案,在这种情况下你可以稍微简化一下调用代码(想法来自@Nawaz在这个答案):
#define TEMPLATE_CONST(x) template_const<decltype(x), x>
int main()
{
int i = 512, j = 256;
TEMPLATE_CONST(123)(i, j);
TEMPLATE_CONST(true)(i, j);
}
Run Code Online (Sandbox Code Playgroud)