简体   繁体   中英

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? 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. 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.

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

An explicit specialization may be declared in any scope in which the corresponding primary template may be defined ([namespace.memdef], [class.mem], [temp.mem]).

This was adopted for the C++17 but has also been retroactively applied to 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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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