函数模板重载差异

use*_*568 16 c++ language-lawyer

尝试重载函数和函数模板时,我得到不同的行为.功能:

void foo(int)
{
    std::cout << "int";
}

void foo(char)
{
    std::cout << "char";
}
Run Code Online (Sandbox Code Playgroud)

foo(42)int.但对于功能模板:

template <int T>
void bar()
{
    std::cout << "int T";
}

template <char T>
void bar()
{
    std::cout << "char T";
}
Run Code Online (Sandbox Code Playgroud)

bar<42>()是暧昧的电话.即使我使用char,也会发生这种情况bar<'a'>().为什么一个工作而另一个工作?

Ale*_*exD 7

标准N4140(归功于MM)在14.8.2模板参数推导中给出了这个解释和样本:

9除上述情况外,使用无效值不应导致类型扣除失败.[ 示例: 在以下示例中,1000转换为signed char并生成(4.7)中指定的实现定义值.换句话说,即使1000转换为signed char,也会考虑两个模板,从而产生实现定义的值.

template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1>(0);    // ambiguous
int i2 = f<1000>(0); // ambiguous
Run Code Online (Sandbox Code Playgroud)

- 结束例子 ]

但请注意,在以下草稿中,规则会更改,因为:

这不再正确,甚至忽略了一些实现可能能够将值1000表示为signed char:整数和枚举非类型模板参数现在转换为常量表达式的事实(14.3.2 [temp.arg.nontype]第1段)和转换后的常量表达式不允许缩小转换(5.20 [expr.const]第3段).

拟议的样本是:

template <int> int f(int);
template <signed char> int f(int);

int i1 = f<1000>(0); // OK
int i2 = f<1>(0);    // ambiguous; not narrowing
Run Code Online (Sandbox Code Playgroud)