如何分配具有不同模板参数的两个容器

时间:2012-07-25 17:12:25

标签: c++ templates

我们假设我有一个类容器:

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数组这样的类允许这样做。
怎么做?

3 个答案:

答案 0 :(得分:2)

模板只是 - 编译器用来创建类的模板,而不是类本身。

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

特别是,这意味着container<int, 4>的分配运算符无法访问private的{​​{1}}成员。

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

  • 消除大小模板参数,因为正如其他人所说,你似乎是动态分​​配内存,所以在编译时确定大小不会增加任何值,事实上可能会产生误导,因为你的赋值运算符可能会导致与宣称的大小不同。
  • 根据container<int,5>的公共接口实现您的赋值运算符。
  • 通过在您的班级中添加以下内容来声明与container相同类型的所有container类:

代码:

friends

并按如下方式声明赋值运算符:

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

答案 1 :(得分: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;
    }

答案 2 :(得分: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());