在classtemplate中遇到两个不同对象的问题

时间:2014-11-30 01:40:02

标签: c++ class templates

我遇到了readdata函数的问题,并将数组A转换为同一函数中的字符串类型。如果您发现任何问题,我已经发布了以下代码,我将非常感谢任何反馈。

#include <iostream>
#include <algorithm>
#include <ctime>
#include <string>
using namespace std;

template <class T, int n>
class TWO
{
private: T a[n];
public: void ReadData();
        void DisplayData();
    void SortArray();
    ~TWO(){}
};

template <class T, int n>
void TWO <T,n> :: ReadData()
{
if (n == 10)
{
    srand(time(0));

    for (int i = 0; i < n; i++)
    {
        a[i] = rand() % 20;
    }
}

else if (n == 12)
{
    a[0] = "Jan";
    a[1] = "Feb";
    a[2] = "Mar";
    a[3] = "Apr";
    a[4] = "May";
    a[5] = "Jun";
    a[6] = "Jul";
    a[7] = "Aug";
    a[8] = "Sep";
    a[9] = "Oct";
    a[10] = "Nov";
    a[11] = "Dec";
}
}


template <class T, int n>
void TWO <T,n> ::DisplayData()
{
   for (int i = 0; i < n; i++)
{
    cout << a[i] << " ";
}

cout << endl;
}

template <class T, int n>
void TWO <T, n> ::SortArray()
{
sort(a, a + n);
}

int main()
{
TWO <int, 10> P; 
TWO <string, 12> Q;

P.ReadData();
Q.ReadData();
P.DisplayData();
Q.DisplayData();
P.SortArray();
Q.SortArray();
P.DisplayData();

system("pause");

return 0;
}

2 个答案:

答案 0 :(得分:1)

这里的问题是您尝试使用不同类型的数据初始化相同的成员变量。这不会以您当前拥有代码的方式工作,因为无论使用何种类型,都将实例化整个函数。当模板参数Tint时,该函数正在尝试将字符串分配给数组。当模板参数T是一个字符串时,该函数试图将整数分配给数组。

为了解决这个问题,您可以使用特化并将其拆分为两个不同的函数,并让编译器根据模板参数实例化正确的函数。

template <>
void TWO <string, 12>::ReadData()
{
    a[0] = "Jan";
    a[1] = "Feb";
    a[2] = "Mar";
    a[3] = "Apr";
    a[4] = "May";
    a[5] = "Jun";
    a[6] = "Jul";
    a[7] = "Aug";
    a[8] = "Sep";
    a[9] = "Oct";
    a[10] = "Nov";
    a[11] = "Dec";
}

template <>
void TWO <int, 10>::ReadData()
{
    srand(time(0));

    for (int i = 0; i < 10; i++)
    {
        a[i] = rand() % 20;
    }
}

请记住,如果模板参数与可用的专业化不完全匹配,则会出现链接时错误。如果您使用的是C ++ 11,则可以通过在函数的非专用版本中使用static_assert来使这一点更加明显

template <class T, int n>
void TWO <T, n>::ReadData()
{
    static_assert(0, "Specialization not available");
}

如果模板参数不是<int, 10><string, 12>,则会导致编译时错误。

同样根据评论中的建议,您应该在srand而不是main函数中调用ReadData

答案 1 :(得分:0)

问题是代码试图分配与类型T不匹配的值。由于类型字符串和int完全不同,因此ReadData()成员函数的泛型定义不起作用。一种解决方案是用相应的专业化取代这样的定义:

template<>
void TWO <int,10> :: ReadData()
{
    const int n = 10;
    srand(time(0));

    for (int i = 0; i < n; i++)
    {
        a[i] = rand() % 20;
    }
}

template<>
void TWO <string,12> :: ReadData()
{
    a[0] = "Jan";
    a[1] = "Feb";
    a[2] = "Mar";
    a[3] = "Apr";
    a[4] = "May";
    a[5] = "Jun";
    a[6] = "Jul";
    a[7] = "Aug";
    a[8] = "Sep";
    a[9] = "Oct";
    a[10] = "Nov";
    a[11] = "Dec";
}