【问题标题】:template function instantiation and specialization模板函数实例化和特化
【发布时间】:2014-03-07 01:44:01
【问题描述】:

对模板函数有点困惑。我有以下内容:

template <class T> T max (T v1, T v2)

double max(double v1, double v2)        // non template 

1)

int a = max(100, 200);  // assuming max<int> is instantiated based on input param

2)

int a = max<int>(100.1, 200.1);  // specialization triggers input type conversion

3)

double p = max<double>(100.1, 200.1);   // specialization

4)

double p = max(100.1, 200.1);          // non-template function used

(1) 没有 max 的调用是否有效?编译器如何处理这个? (3vs4) 编译器如何跟踪调用 max(double>() v/s max()?

【问题讨论】:

    标签: c++ function templates


    【解决方案1】:

    所有都是完全有效的,如果输入/输出匹配,编译器会在大多数情况下找出你想要的。

    请注意,通过为doubles 声明一个新的max 函数,您已经告诉它您希望以特殊方式处理它们,它会搜索您的特殊实现。这允许您在默认模板可能不起作用的特殊情况下。

    【讨论】:

      【解决方案2】:

      从重载中选择时,编译器首先检查非模板版本。由于不鼓励隐式转换,编译器不会将其视为完美选择。然后编译器检查模板版本并找到它的真爱(两者都不需要改变自己,它们都适合)。

      但是考虑一下这种情况

      double max(double v1, double v2);
      
      template <typename T>
      T max(double v1, double v2);
      
      int a = max(1,2);
      

      如果您让编译器显示最高级别的警告(例如:VS 中的 W4),您会在编译器选择非模板版本时收到警告 C4244(将 double 转换为 int)。编译器在选择时不考虑返回值。

      【讨论】:

        【解决方案3】:

        函数模板重载有规则:

        “如果一个函数和一个特化同样好匹配,那么这个函数是首选的。”

        因此,max(double, double) 优于 max&lt;double&gt;(double, double)

        编译器可以将普通函数与模板实例化候选者和gives precedence 与非模板区分开来,因为它“更真实”。

        编译器如何区分函数?它使用name mangling,比如adding a letter 'H' 作为模板实例化函数。名称修饰的确切方式是特定于编译器的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多