关于模板默认参数的问题

kejie1235 2013-08-01 08:08:49

#include <cstdlib>
#include <iostream>
#include <iterator>

using namespace std;

template <class T, size_t N =20 >
class Array {

private:
T *data;
size_t count;
size_t capacity;

public:

Array(){
count = 0;
data = new T[capacity = N];
}

~Array(){
delete []data;
}

void push_back(const T &t)
{
if(count == capacity)
{
T *newdata = new T[2*capacity];

for(int i=0; i<count; ++i)
newdata[i] = data[i];

delete data;
data = newdata;

capacity = 2*capacity;
data[count++] = t;
}
else
data[count++] = t;
}

void pop_back()
{
if(count > 0)
--count;
else
cout<<"count == 0"<<endl;

}

T* begin(){
return data;
}

T* end(){

return data+count;
}

};

template<class T, template<class,size_t N = 20> class seq >

class Container{

private:
seq<T> sq;

public:

void append(T &t)
{
sq.push_back(t);
}

T* begin(){

return sq.begin();
}

T* end(){

return sq.end();
}


};


int main()
{
Container<int,Array > con;
for(int i =10; i< 60; i += 10)
con.append(i);

//Array<T>::iterator it = con.begin();

int *it = con.begin();
for(; it!= con.end(); ++it)
cout<<*it<<endl;


return 1;
}



如果我想从主函数中传入 数组元素个数30,该怎么改写?
...全文
163 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-08-02
  • 打赏
  • 举报
回复
看看 std::vector的做法把 // int a[20]; // 用数组a 的前20个元素初始化 vector std::vector v(a,a+20);
飞天御剑流 2013-08-01
  • 打赏
  • 举报
回复
引用 6 楼 kejie1235 的回复:
请大神给个提示,另外还有个问题,我想使用Array<int>::iterator it = con.begin(),可是需要在Array中实现

typedef random_access_iterator_tag iterator_tag;
    typedef T value_type;
    typedef T* iterator;
    typedef T& reference;
    typedef ptrdiff_t difference_type;
这只是其中一种方法,还有另外一种方式 Array继承C++标准库汇中的: public iterator<random_access_struct_tag>,可是我继承的时候 编译器说不存在在iterator,可是我不知道stl库中的iterator到C++标准库中变成了什么。以下示例是通过第一种方法实现的,而第二种方式向大神请教

#include <cstdlib>
#include <iostream>
#include <iterator>

using namespace std;

template <class T, size_t N =20 >
class Array /*: public iterator<random_access_iterator_tag, T> */{

private:
    T *data;
    size_t count;
    size_t capacity;

public:

    Array(){
        count = 0;
        data = new  T[capacity = N];
    }

    ~Array(){
        delete []data;
    }

    void push_back(const T &t)
    {
        if(count == capacity)
        {
                T *newdata = new T[2*capacity];

                for(int i=0; i<count; ++i)
                    newdata[i] = data[i];

                delete data;
                data = newdata;

                capacity = 2*capacity;
                data[count++] = t;
        }
        else
            data[count++] = t;
    }

    void pop_back()
    {
        if(count > 0)
            --count;
        else
            cout<<"count == 0"<<endl;

    }

    T* begin(){
        return data;
    }

    T* end(){

        return data+count;
    }

    T* operator++()
    {
        this++;
        return this;
    }


    typedef random_access_iterator_tag iterator_tag;
    typedef T value_type;
    typedef T* iterator;
    typedef T& reference;
    typedef ptrdiff_t difference_type;
};

template<class T,size_t N , template<class,size_t N = 20> class seq >

class Container{

private:
    seq<T,N> sq;

public:

    void append(T &t)
    {
        sq.push_back(t);
    }

    T* begin(){

        return sq.begin();
    }

    T* end(){

        return sq.end();
    }


};


int main()
{
    Container<int> con = Array;
    for(int i =10; i< 60; i += 10)
        con.append(i);

    Array<int>::iterator it = con.begin();

    for(; it!= con.end(); ++it)
        cout<<*it<<endl;


    return 1;
}

你不应该用你的Array去继承std::iterator,因为Array是“含有”iterator,而非“是”iterator,应该这样做:

template< typename T >
class MyIterator : public std::iterator< std::random_access_iterator_tag, T >
{
public :

    MyIterator( T* iter ) : _iter( iter ){}
    T* operator ++ ( )
    {
        return ++_iter;
    }
    T& operator * ( )
    {
        return *_iter;
    }
    ........  //随机迭代器其它各种运算的实现

private :

    T* _iter;
};
............
template <class T, size_t N =20 >
class Array
{
public :    
    .........
    typedef MyIterator< T > iterator;
    typedef typename MyIterator< T >::value_type value_type;
    typedef typename MyIterator< T >::iterator_category iterator_category;
    typedef typename MyIterator< T >::reference reference;
    typedef typename MyIterator< T >::difference_type difference_type;
    typedef typename MyIterator< T >::pointer pointer;
};
在河之洲 2013-08-01
  • 打赏
  • 举报
回复
很赞同二楼的说法 小弟最近在学习c++ 不过不懂你这个是在干什么 为什么array封装在container里面呢
飞天御剑流 2013-08-01
  • 打赏
  • 举报
回复
还有个解法,可以如下这样: template <class T, size_t N > class Array ............. template<class T, typename seq = Array< T, 20 > > class Container { private: seq sq; ........... Container< int > con; //默认20元素的数组 Container< int, Array< int, 30 > > con; //30元素的数组 但我觉得2楼的解法更好一些。
kejie1235 2013-08-01
  • 打赏
  • 举报
回复
请大神给个提示,另外还有个问题,我想使用Array<int>::iterator it = con.begin(),可是需要在Array中实现

typedef random_access_iterator_tag iterator_tag;
    typedef T value_type;
    typedef T* iterator;
    typedef T& reference;
    typedef ptrdiff_t difference_type;
这只是其中一种方法,还有另外一种方式 Array继承C++标准库汇中的: public iterator<random_access_struct_tag>,可是我继承的时候 编译器说不存在在iterator,可是我不知道stl库中的iterator到C++标准库中变成了什么。以下示例是通过第一种方法实现的,而第二种方式向大神请教

#include <cstdlib>
#include <iostream>
#include <iterator>

using namespace std;

template <class T, size_t N =20 >
class Array /*: public iterator<random_access_iterator_tag, T> */{

private:
    T *data;
    size_t count;
    size_t capacity;

public:

    Array(){
        count = 0;
        data = new  T[capacity = N];
    }

    ~Array(){
        delete []data;
    }

    void push_back(const T &t)
    {
        if(count == capacity)
        {
                T *newdata = new T[2*capacity];

                for(int i=0; i<count; ++i)
                    newdata[i] = data[i];

                delete data;
                data = newdata;

                capacity = 2*capacity;
                data[count++] = t;
        }
        else
            data[count++] = t;
    }

    void pop_back()
    {
        if(count > 0)
            --count;
        else
            cout<<"count == 0"<<endl;

    }

    T* begin(){
        return data;
    }

    T* end(){

        return data+count;
    }

    T* operator++()
    {
        this++;
        return this;
    }


    typedef random_access_iterator_tag iterator_tag;
    typedef T value_type;
    typedef T* iterator;
    typedef T& reference;
    typedef ptrdiff_t difference_type;
};

template<class T,size_t N , template<class,size_t N = 20> class seq >

class Container{

private:
    seq<T,N> sq;

public:

    void append(T &t)
    {
        sq.push_back(t);
    }

    T* begin(){

        return sq.begin();
    }

    T* end(){

        return sq.end();
    }


};


int main()
{
    Container<int> con = Array;
    for(int i =10; i< 60; i += 10)
        con.append(i);

    Array<int>::iterator it = con.begin();

    for(; it!= con.end(); ++it)
        cout<<*it<<endl;


    return 1;
}

飞天御剑流 2013-08-01
  • 打赏
  • 举报
回复
当使用N的默认值时,是不能使用seq的实参的,这是默认参数的基本知识,你只能Container< int >,如果你认为seq使用实参的情况比N要多,可以将seq调到前头去,例如: template<class T, template<class,size_t N > class seq = Array, size_t N = 20, > 这样就可以Container<int,Array>了。
turing-complete 2013-08-01
  • 打赏
  • 举报
回复
seq = Array<T, 20>
kejie1235 2013-08-01
  • 打赏
  • 举报
回复
这时我想使用默认20参数,这时主函数Container<int,Array>就行了,可是这时编译器会报错,说参数少了。请问该怎么办?
飞天御剑流 2013-08-01
  • 打赏
  • 举报
回复
由于模板的模板参数中的形参是无法直接引用的(它实际上只不过一个占位符),所以需要手工传入实参的话,就不能象上面那样写了,得把N抽出来,如下:

template <class T, size_t N >
class Array
.............
template<class T, size_t N = 20, template<class,size_t N > class seq = Array >
class Container
{

private:
    seq< T, N > sq;
...........

int main( void )
......
Container<int, 30 > con;
........
turing-complete 2013-08-01
  • 打赏
  • 举报
回复
这是在练习什么? 适配器? 看不透你的意图

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧