正如@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);
}
这并不理想,但它认为没有更清洁的解决方案,除非您可以使用 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);
}