简体   繁体   English

类成员函数的函数模板特化

[英]Function template specialization of a class member function

#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;
}

Getting the following compilation errors: 获得以下编译错误:

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

Error 1: Is there a workaround for this? 错误1:有解决方法吗? Is specialization not allowed at all for non-namespace scope (the class in this case)? 对于非命名空间范围(在这种情况下是类),是否完全不允许专门化?

Error 2: I am aware of the fact that partial specialization of function templates are not allowed. 错误2:我知道不允许对函数模板进行部分特化。 However, I am not getting how this is a partial specialization? 但是,我没有得到这是如何部分专业化? Any workaround? 任何解决方法?

Note: If the functions are not class member methods, the code compiles fine. 注意:如果函数不是类成员方法,则代码编译正常。

In C++11 [temp.expl.spec]/2 requires that explicit specializations of template functions happen in namespace scope. 在C ++ 11中,[temp.expl.spec] / 2要求模板函数的显式特化在命名空间范围内发生。

An explicit specialization shall be declared in a namespace enclosing the specialized template. 应在包含专用模板的命名空间中声明显式特化。 [...] [...]

Because of that you have to use 因为你必须使用

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    ";
}

That said DR CWG 727 has since been applied and clang (8.0.0+) and MSVS(2015 update 3+) will compile the code as the new wording for [temp.expl.spec]/2 is 那说DR CWG 727已被应用并且clang(8.0.0+)和MSVS(2015 update 3+)将编译代码,因为[temp.expl.spec] / 2的新措辞是

An explicit specialization may be declared in any scope in which the corresponding primary template may be defined ([namespace.memdef], [class.mem], [temp.mem]). 可以在可以定义相应主模板的任何范围中声明显式特化([namespace.memdef],[class.mem],[temp.mem])。

This was adopted for the C++17 but has also been retroactively applied to C++14 这是C ++ 17采用的,但也被追溯应用于C ++ 14


There has been a bug report submitted for gcc but it has no progresss on it yet: Bug 85282 - CWG 727 (full specialization in non-namespace scope) 已经为gcc提交了一个错误报告,但它还没有进展: Bug 85282 - CWG 727(非命名空间范围内的完全专业化)

Probably a duplicate question, but the answer is short: 可能是一个重复的问题,但答案很简短:

Do the specialization outside the class definition, ie: 在类定义之外进行专门化,即:

class test
{ ... };

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

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM