明确的实例化

时间:2010-09-16 04:05:55

标签: c++ templates explicit-specialization

这是由this文章(第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'以匹配对显式特化'f<int>'的调用。但看起来这是不合理的?

标准的哪一部分讨论了此背景下适用的规则?

3 个答案:

答案 0 :(得分:5)

不,呼叫f(x, s)格式不正确。由于您没有明确说明要使用的特化,编译器使用参数推导来尝试实例化函数模板;此操作失败,因为xs的类型不同,因此T不明确。

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

  

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

14.8.3 / 1也是相关的:

  

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

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

答案 1 :(得分:3)

调用f(x, s)在语法上是格式良好的,但编译器将无法从中推导出模板参数T,因为可能是int或{{1} (因为第一个和第二个参数)。实例化模板没有帮助,只表示编译器编译该特化并将其添加到生成的目标文件中。

如果您希望自动将short投射到s,请使用int

答案 2 :(得分: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) );
}