1

假设我有一个类容器:

template<class T, int size>
class container
{
private:
    T* data;
    int length;
public:
    container()
    {
        data=new T[size];
        length=size;
    }
    ~container()
    {
        if(length>0)
            delete[] data;
    }
    container& operator= (container<T,size> c)
    {
        if(length>0)
           delete[] data;
        data=new T[c.length];
        length=c.length;
        for(int i=0; i<length; i++)
            data[i]=c.data[i];
        return *this;
    }
};

问题是,如果我有两个不同大小的容器,我不能使用 = 运算符将一个分配给另一个。例如:

container<int,4> c1;
container<int,5> c2;
c1=c2;  // syntax error: 4!=5

像 c++11 数组这样的类允许这样做。
怎么做?

4

3 回答 3

2

模板就是这样——编译器用来创建类的模板,而不是类本身。

因此,container<int,4>container<int,5>是完全独立的类,具有所暗示的所有访问限制。

特别是,这意味着container<int, 4>的赋值运算符不能访问 的private成员container<int,5>

有几种方法可以解决这个问题:

  • 消除 size 模板参数,因为正如其他人所指出的那样,您似乎在动态分配内存,因此在编译时确定大小不会增加任何价值,实际上可能会产生误导,因为您的赋值运算符可能会导致不同的尺寸大于声明的尺寸。
  • container根据的公共接口实现您的赋值运算符。
  • 通过将以下行添加到您的类来声明所有container具有相同类型的类:friends

代码:

template<class U, int otherSize> friend class Foo;

并声明您的赋值运算符如下:

template <int otherSize>
container<T,size>& operator=(container<T,otherSize> c);
于 2012-07-25T18:02:00.053 回答
1

您需要使用要从中分配的容器大小对分配运算符进行参数化(忽略已发布代码的任何其他问题):

    template <int otherSize>
    container& operator= (container<T,otherSize> c)
    {
        if(length>0)
           delete[] data;
        data=new T[otherSize];
        length=otherSize;
        for(int i=0; i<otherSize; i++)
            data[i]=c.data[i];
        return *this;
    }
于 2012-07-25T17:27:47.990 回答
0

正如评论者所指出的,将初始大小作为模板参数看起来是错误的,并且是问题的根源。

但是考虑到从两个不兼容的容器分配的一般问题,您可以将模板operator=化为 tumdum 的答案显示,但是当您想从另一个稍微不同的类型填充容器时,这无济于事。

标准容器通过允许从由一对迭代器定义的范围进行构造和分配来解决问题:

template<typename FwdIter>
  container(FwdIter begin, FwdIter end)
  {
    data=new T[length = std::distance(begin, end)];
    std::copy(begin, end, data);
  }

template<typename FwdIter>
  void
  assign(FwdIter begin, FwdIter end)
  {
    container(begin, end).swap(*this);
  }

void swap(container& c)
{
  std::swap(data, c.data);
  std::swap(length, c.length);
}

iterator begin() { return data; }
const_iterator begin() const { return data; }
const_iterator cbegin() const { return data; }
iterator end() { return data+size; }
const_iterator end() const { return data+size; }
const_iterator cend() const { return data+size; }

现在你可以这样做:

container<int,4> c1;
container<int,5> c2;
c1.assign(c2.begin(), c2.end());
于 2012-07-25T17:51:17.127 回答