【问题标题】:Function template specialization of a class member function类成员函数的函数模板特化
【发布时间】:2018-08-09 12:49:08
【问题描述】:
#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:我知道函数模板的部分特化是不允许的。但是,我不知道这是部分专业化吗?有什么解决方法吗?

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

      Demo

      【讨论】:

        猜你喜欢
        • 2012-04-03
        • 1970-01-01
        • 2011-08-22
        • 2013-09-24
        • 1970-01-01
        • 1970-01-01
        • 2013-12-20
        相关资源
        最近更新 更多