首页 > 解决方案 > 函数模板专业化真的允许吗?

问题描述

根据这篇文章,它说(强调我的):

部分模板专业化允许我们专门化类(但不能专门化单个函数!)

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

让我困惑的是,为什么这些代码片段可以编译成功:

//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)

}

为什么这个代码段无法编译,而前面的两个代码段编译成功?

#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<class N> void compare(int num1, N num2)模板重载 template <class T2> void f<int, T2>(){}试图部分特化函数模板?

标签: c++c++11templates

解决方案


函数模板专业化真的允许吗?

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

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

如果您的意思是部分专业化,那么函数模板确实不允许这样做。

// 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

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

为什么无法编译此代码段

因为它试图部分专门化一个函数模板。


如何区分重载模板和部分特化功能模板?

函数特化的语法是:

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

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


推荐阅读