正如 @jogojapan 指出的,问题在于编译器无法对这两个函数进行排序,即没有一个比另一个更专业。如第 14.5.6.2 节中所述,当对重载函数模板的调用不明确时,编译器会使用各种重载之间的偏序来选择最专业的一个。
为了对重载进行排序,编译器会转换它们中的每一个并执行模板参数推导,以查看其中一个是否比另一个更专业(在末尾有一个简短的解释)这个答案)。在您的情况下,两个重载是等效的(或不具有可比性):template<int> void template_const(int &,int &)
并不比更专业template<bool> void template_const(int &, int &)
,反之亦然。
因此,编译器无法选择其中之一,从而生成一个ambiguous call
error.
如果您可以明确指定要传递的参数的类型,则可以使用部分模板专业化,如下所示:
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);
}