类成员函数的函数模板专业化

时间:2018-08-09 12:49:08

标签: c++ c++11 templates overloading template-specialization

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

class test
{

    public:

    template <typename T>
    void f(const std::string& path, std::vector<T>& type_vec)
    {
        cout << "Base template   "; 
    }

    template <>
    void f<std::string>(const std::string& path, std::vector<std::string>& type_vec)
    {
        cout << "Specialization vec    ";
    }
};

int main()
{
    std::vector<int> vec_int;
    std::vector<std::string> vec_str;
    std::string path = "";
    test T;

    T.f(path, vec_int);
    T.f(path, vec_str);

    return 0;
}

出现以下编译错误:

main.cpp:24:15: error: explicit specialization in non-namespace scope 'class test'
     template <>
               ^
main.cpp:25:84: error: template-id 'f' in declaration of primary template
     void f<std::string>(const std::string& path, std::vector<std::string>& type_vec)
                                                                                    ^

错误1:是否有解决方法?非命名空间范围(在这种情况下为类)完全不允许专门化吗?

错误2:我知道不允许对功能模板进行部分专业化的事实。但是,我不明白这是如何部分专业化的?有解决方法吗?

注意:如果函数不是类成员方法,则代码可以正常编译。

2 个答案:

答案 0 :(得分:6)

在C ++ 11中,[temp.expl.spec] / 2要求模板函数的显式专业化在名称空间范围内发生。

  

显式专门化应在包含专门化模板的命名空间中声明。 [...]

因此,您必须使用

class test
{

    public:

    template <typename T>
    void f(const std::string& path, std::vector<T>& type_vec)
    {
        cout << "Base template   "; 
    }
};

template <>
void test::f<std::string>(const std::string& path, std::vector<std::string>& type_vec)
{
    cout << "Specialization vec    ";
}

DR CWG 727已被应用,而clang(8.0.0+)和MSVS(2015更新3+)将编译代码,因为[temp.expl.spec]/2的新措辞是

  

可以在可以定义相应主模板的任何范围([namespace.memdef],[class.mem],[temp.mem])中声明显式专业化。

这是C ++ 17所采用的,但也追溯适用于C ++ 14


已经提交了一份针对gcc的错误报告,但尚无进展:Bug 85282 - CWG 727 (full specialization in non-namespace scope)

答案 1 :(得分:1)

可能是重复的问题,但答案很短:

在类定义之外进行专业化,即:

class test
{ ... };

template <>
void test::f<std::string>(const std::string& path, std::vector<std::string>& type_vec)
{
    cout << "Specialization vec    ";
}

Demo