【问题标题】:Is function template specialization really allowed?函数模板专业化真的允许吗?
【发布时间】:2021-01-02 03:36:21
【问题描述】:

根据this article,它说(强调我的):

部分模板特化允许我们特化类(但 不是单个函数!)

似乎不允许函数部分模板特化。这真的正确吗?

让我困惑的是为什么这些代码sn-ps可以编译成功:

//demo1.cpp
//first code snippet(https://coliru.stacked-crooked.com/a/0868610b5be94f2c)
//Why this function template specialization compiles? 
//Because this is full template specialization other than partial template specialization?Am I right?
#include <iostream>
#include <string.h>
using namespace std;

template <class T>
void f(T)
{ 
    T d; 
    std::cout <<"first one" << std::endl;
}
    
template <>
void f<int>(int)
{ 
    int d;
    std::cout <<"second one" << std::endl;
}

int main() 
{
    f(5.0);
    f(1);
    f('a');
}

另一个例子:

//demo2.cpp(https://coliru.stacked-crooked.com/a/7b1a94ad377ac1f6)
//Why this function template specialization compiles? 
//I think it's function partial template specialization indeed.
#include <vector>
#include <iostream> 
using namespace std;

//function template
template<typename T, class N> void compare(T num1, N num2) {
    cout << "standard function template" << endl;
    if(num1>num2)
        cout << "num1:" << num1 << " > num2:" << num2 <<endl;
    else
        cout << "num1:" << num1 << " <= num2:" << num2 << endl;
}

//function partial template specialization
template<class N> void compare(int num1, N num2) {
    cout<< "partitial specialization" <<endl;
    if (num1>num2)
        cout << "num1:" << num1 << " > num2:" << num2 << endl;
    else
        cout << "num1:" << num1 << " <= num2:" << num2 << endl;
}

int main() {
    compare<int,int>(30,31);//call compare<int,int>(int num1, int num2)
    
    compare(5,9);           //call compare<int>(int num1, int num2)

    compare(30,'1');        //call compare<char>(int num1, char num2)

}

为什么this code snippet无法编译,而上述两个代码sn-ps编译成功?

#include <vector>
#include <iostream> 
using namespace std;

template <class T1, class T2>
void f(){}
    
template <class T2>
void f<int, T2>(){}  //It's function template sepcialization, isn't it? Why it could not be compiled?

int main() {}

以下是错误消息:

main.cpp:9:6: error: non-type partial specialization 'f<int, T2>' is not allowed
    9 | void f<int, T2>(){}
      |      ^~~~~~~~~~

已编辑: 感谢 eerorika 的详细解释。

还有一个问题,如何区分重载模板和部分特化函数模板?

换句话说,为什么 template&lt;class N&gt; void compare(int num1, N num2) 是模板重载 template &lt;class T2&gt; void f&lt;int, T2&gt;(){} 正在尝试对函数模板进行部分特化?

【问题讨论】:

    标签: c++ c++11 templates


    【解决方案1】:

    真的允许函数模板特化吗?

    是的,但不是部分专业化。

    好像函数部分模板特化是不允许的,真的正确吗?

    如果你的意思是部分专业化,那对于函数模板来说确实是不允许的。

    // Why this fucntion template specialization compiles? 
    // Because this is full template specialization ...?Am I right?
    

    是的。

    //Why this fucntion template specialization compiles? 
    //I think it's function partcial template specialization
    

    不,那根本不是模板专业化。那是一个单独的模板。这是一个超载。

    为什么这段代码 sn-p 无法编译

    因为它试图对函数模板进行部分特化。


    如何区分重载模板和部分特化函数模板?

    函数特化的语法是:

    template<>
    ReturnType template_name<template_argument_list>(parameter_list) {
    //                      ^^^^^^^^^^^^^^^^^^^^^^^^
    

    如果语法不是 this,那么它就不是函数特化。请注意您的示例中缺少的突出显示的部分,它不是专业化的。如果该部分被遗漏,这将成为主要模板定义。

    【讨论】:

    • 又提出一个问题,如何区分重载模板和部分特化函数模板?感谢您的详细解释。换句话说,为什么 template void compare(int num1, N num2) 是模板重载,而 template void f(){} 试图部分特化函数模板?
    • 非常感谢。在您的慷慨帮助下,我对这个问题的理解在不同的层面上。
    【解决方案2】:

    回答我的最后一个问题。

    如果它试图专门化一个函数模板,它的语法应该看起来有点像下面的。

    //attempt to specialise a function template
    template<class N> void compare<int, N>(int num1, N num2) {
        cout<< "partitial specialization" <<endl;
        if (num1>num2)
            cout << "num1:" << num1 << " > num2:" << num2 << endl;
        else
            cout << "num1:" << num1 << " <= num2:" << num2 << endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 2011-10-29
      • 2013-12-27
      • 2015-07-04
      相关资源
      最近更新 更多