1

这是由这篇文章引起的(第5页)

template<class T> 
T const &f(T const &a, T const &b){
    return (a > b ? a : b);
}

template int const &f<int>(int const &, int const &);

int main(){
    int x = 0, y = 0;
    short s = 0;
    f(x, y);     // OK
    f(x, s);     // Is this call well-formed?
}

通话'f(x, s)'格式是否正确?我假设由于函数模板'f'是显式实例化的,因此将应用标准转换,因此'short s'将转换'int'为匹配对显式 specialization 的调用'f<int>'。但这似乎是不正确的?

标准的哪一部分谈到了在这种情况下的适用规则?

4

3 回答 3

5

不,通话f(x, s)格式不正确。由于您没有明确说明要使用的特化,编译器使用参数推导来尝试实例化函数模板;这失败了,因为x并且s有不同的类型,所以T是模棱两可的。

适用规则在 13.3.1 中的重载解决过程规范中:

在候选函数模板的每种情况下,候选函数模板特化是使用模板参数推导(14.8.3、14.8.2)生成的。然后以通常的方式将这些候选函数作为候选函数处理。

14.8.3/1 也相关:

对于每个函数模板,如果参数推导和检查成功,则模板参数(推导和/或显式)用于实例化单个函数模板特化,该特化被添加到候选函数集以用于重载决议。如果对于给定的函数模板,参数推导失败,则不会将此类函数添加到该模板的候选函数集中。

函数模板被显式实例化T = int,但编译器不知道它应该使用这个实例化,直到它执行模板参数推导以确定T应该是什么。

于 2010-09-16T05:18:14.730 回答
3

该调用f(x, s)在语法上格式正确,但编译器将无法从中推断出模板参数T,因为它可以是 aint或 a short(因为第一个和第二个参数)。实例化模板无济于事,这只表明编译器编译该专业化并将其添加到生成的目标文件中。

如果您希望调用自动转换s为 a int,请使用f<int>(x, s).

于 2010-09-16T04:09:08.747 回答
1

显式实例化的特化没有任何更高的优先级或优惠待遇。从实例化的角度来看,它只是完整地存在。对图书馆有用。

编译器根本无法确定要转换哪个参数,并且就像没有额外声明一样被卡住。

顺便说一句,如果你返回一个对已转换参数的引用,一旦临时过期,它将悬空。如果参数是对不同类型的引用,则无法正确形成返回值。

这是我的更新min

#include <type_traits>

template< typename A, typename B >
typename std::common_type< A, B >::type // cannot return ref
my_min( A const &a, B const &b ) {
    return a < b? a : b;
}

 // enable_if< is_same< A, B > > the old, return-by-reference impl

int main() {
    int q = my_min( short(5), long(3) );
}
于 2010-09-16T05:19:29.030 回答