仅在头文件中的静态模板化成员函数的模板行为

时间:2017-07-14 12:57:26

标签: c++ templates c++14 template-specialization

private List<ChartData> data = new List<ChartData>();
private List<double> dataX = new List<double>();

void updateMaxMin()
        {
            dataX.Clear();
            dataY.Clear();

            for (int i = 0; i < data.Count - 1; i++)
            {
                dataX.Add(data[i].X);
                dataY.Add(data[i].Y);
            }
        }

我写了上面的类并尝试编译它。   我收到了以下错误:

  

错误:非命名空间范围中的显式特化&#39;类Myclass&#39;
  错误:template-id&#39; func&#39;在主要模板的声明中

然后我把我的静态函数移出了这个类:

class Myclass
{

    template <typename T>
    static T func()
    {
        T obj;
        return obj;
    }

    template<>
    static int func<int>()
    {

    }

};

我收到了以下错误:

  

错误:显式模板专业化不能有存储类
   在静态成员函数&#39;静态T Myclass :: func()&#39;:

然后当然我内联我的专业功能,它工作。

namespace helper 
{
    template <typename T>
    static T func()
    {
        T obj;
        return obj;
    }

    template<>
    static int func<int>()
    {

    }
}

class Myclass
{
  template <typename T>
  static T func()
  {
      helper::func<T>();
  }

};

我的问题是:
1)为什么我们不能专门研究班级内的静态成员函数 2)为什么我们不能拥有静态模板专用函数

2 个答案:

答案 0 :(得分:1)

老实说,这两个问题的真正答案可能是“因为。”

您可以专门化一个成员函数模板,它只需要在类之外,不能使用static关键字:

struct Myclass {
    template <class T>
    static T func() {
        T obj{};
        return obj;
    }
};

template <>
int Myclass::func<int>() { return 42; }

两者都是语法上的原因。这只是你必须要记住的事情之一。

答案 1 :(得分:0)

据我所知,C ++不允许在类级别进行成员模板专业化。必须在命名空间级别提供特化,因此您可以在类之外声明特化:

// myclass.h
class MyClass
{
public:

    template <class T>
    void test(T )
    {
        std::cout << "non-specialized test" << std::endl;
    }

    template <class T>
    static T myfunc()
    {
        std::cout << "non-specialized myfunc" << std::endl;
        return T{};
    }
};


template <>
inline void MyClass::test(double t)
{
    std::cout << "specialized test" << std::endl;
}

template <>
static double MyClass::myfunc();

/*template <>
static inline void MyClass::myfunc(double )
{
    std::cout << "specialized myfunc" << std::endl;
}*/

然后在源文件中提供实现:

// myclass.cpp

template <>
static double MyClass::myfunc()
{
    std::cout << "specialized myfunc" << std::endl;
    return 0.0;
}

或者,您可以在标头文件中内联myfunc()(就像test()函数一样)。

关于你的第二个问题,我在VS2015中尝试了它并且它有效。唯一的问题是你缺少返回值。