C++中,一个类模板的内部又嵌套了一个类模板,语法应该是怎么样的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中,一个类模板的内部又嵌套了一个类模板,语法应该是怎么样的相关的知识,希望对你有一定的参考价值。

template <typename T>
class Stack
private:
typedef struct Node
T data;
struct Node *next;
Node;
Node *top;
unsigned int length;
public:
template<typename V>
class const_iterator
friend class Stack<V>;
private:
const Node *p;
public:
explicit const_iterator(Node *ptr);
const V& operator*();
const_iterator& operator++();
const const_iterator operator++(int );
// const const_iterator<V>& operator--();
//const const_iterator<V>& operator--(int );
bool operator==(const const_iterator& iter) const;
bool operator!=(const const_iterator& iter) const;
;

Stack();
unsigned int getLength() const;
void push(T data);
T pop();
T getTop() const;
const_iterator<T> begin() const;
const_iterator<T> end() const;
virtual ~Stack();
protected:

;

template <typename T>
Stack<T>::Stack():top(0), length(0)



template <typename T>
unsigned int Stack<T>::getLength() const

return length;


template <typename T>
void Stack<T>::push(T data)

Node *p = new Node;
p->data = data;
p->next = top;
top = p;
++length;


template <typename T>
T Stack<T>::pop()

Node *p = top;
T data = p->data;
top = top->next;
--length;
delete p;
return data;


template <typename T>
T Stack<T>::getTop() const

return top->data;


template <typename T>
Stack<T>::const_iterator<T> Stack<T>::begin() const

return const_iterator<T>::const_iterator(top);


template <typename T>
Stack<T>::const_iterator<T> Stack<T>::end() const

return const_iterator<T>::const_iterator(0);


template <typename T>
Stack<T>::~Stack()

while(length)
pop();



template <typename T>
Stack<T>::const_iterator<T>::const_iterator(Node *ptr):p(ptr)



template <typename T>
const T& Stack<T>::const_iterator<T>::operator*()

return this->p->data;


template <typename T>
Stack<T>::const_iterator<T>& Stack<T>::const_iterator<T>::operator++()

p = p->next;
return *this;


template <typename T>
Stack<T>::const const_iterator<T> Stack<T>::const_iterator<T>::operator++(int )

const_iterator<T> tmp = *this;
p = p->next;
return tmp;

//const const_iterator<T>& operator--();
//const const_iterator<T>& operator--(int );

template <typename T>
bool Stack<T>::const_iterator<T>::operator==(const const_iterator<T>& iter) const

return p == iter.p;


template <typename T>
bool Stack<T>::const_iterator<T>::operator!=(const const_iterator<T>& iter) const

return !(p == iter.p);

以上是我写的,编译不过,有错误,希望各位大牛能解释一下
现在代码不在手边,晚上新开一个问题,上面的代码我自己修改过了,就只有一个错误,const_iterator里重载后置++运算符这个函数有问题,编译器是gcc 4.8.0,操作系统是Ubuntu 10.04, IDE用的是codeblocks 12.11

刚才在Visual Studio 2010 里试了一下,可以编译通过,但是仍然不知道为什么gcc下不行

写模板辛苦了……

template <typename T>
class Stack
private:
typedef struct Node
T data;
struct Node *next;
Node;
Node *top;
unsigned int length;
public:
class const_iterator
friend class Stack<T>;
private:
const Node *p;
public:
explicit const_iterator(Node *ptr);
const T& operator*();
const_iterator& operator++();
const const_iterator operator++(int );
// const const_iterator<V>& operator--();
//const const_iterator<V>& operator--(int );
bool operator==(const const_iterator& iter) const;
bool operator!=(const const_iterator& iter) const;
;

Stack();
unsigned int getLength() const;
void push(T data);
T pop();
T getTop() const;
const_iterator begin() const;
const_iterator end() const;
virtual ~Stack();
protected:

;

template <typename T>
Stack<T>::Stack():top(0), length(0)



template <typename T>
unsigned int Stack<T>::getLength() const

return length;


template <typename T>
void Stack<T>::push(T data)

Node *p = new Node;
p->data = data;
p->next = top;
top = p;
++length;


template <typename T>
T Stack<T>::pop()

Node *p = top;
T data = p->data;
top = top->next;
--length;
delete p;
return data;


template <typename T>
T Stack<T>::getTop() const

return top->data;


template <typename T>
typename Stack<T>::const_iterator Stack<T>::begin() const

return Stack<T>::const_iterator(top);


template <typename T>
typename Stack<T>::const_iterator Stack<T>::end() const

return const_iterator<T>::const_iterator(0);


template <typename T>
Stack<T>::~Stack()

while(length)
pop();



template <typename T>
Stack<T>::const_iterator::const_iterator(Node *ptr):p(ptr)



template <typename T>
const T& Stack<T>::const_iterator::operator*()

return this->p->data;


template <typename T>
typename Stack<T>::const_iterator& Stack<T>::const_iterator::operator++()

p = p->next;
return *this;


template <typename T>
const typename Stack<T>::const_iterator Stack<T>::const_iterator::operator++(int )

const_iterator<T> tmp = *this;
p = p->next;
return tmp;

//const const_iterator<T>& operator--();
//const const_iterator<T>& operator--(int );

template <typename T>
bool Stack<T>::const_iterator::operator==(const typename Stack<T>::const_iterator& iter) const

return p == iter.p;


template <typename T>
bool Stack<T>::const_iterator::operator!=(const typename Stack<T>::const_iterator& iter) const

return !(p == iter.p);


1、模板类中的某个“类型”(class或者typedef都算)表示的时候要在前面加typename,不然编译器会认为它是成员变量或者成员函数
2、你的const_iterator在Stack<T>里面,故可以使用T作为类型,不进一步指定V也没有关系的
3、这代码我只是给你改到编译能通过而已,没有进一步调试运行是什么情况追答

两个都用模板的情况下,我尝试了好久两边都过不去。

可能你可以参考一下boost里面一些库的写法,那个库里面一大堆变态至极的模板……

追问

我新开过一个提问的,那里的代码在Visual Studio 2010下是可以编译通过的,但是gcc下就是不行,只有你回答的最好,就采纳了。

参考技术A

1、const_iterator 应该是普通类

2、使用typename高速编译器Stack<T>是一个类型, 防止报error C2143

修改后代码如下:

template <typename T>
class Stack

private:
typedef struct Node

T data;
struct Node *next;
Node;
Node *top;
unsigned int length;
public:
class const_iterator
friend class Stack<T>;
private:
const Node *p;
public:
explicit const_iterator(Node *ptr);
const T& operator*();
const_iterator& operator++();
const const_iterator operator++(int ); // const const_iterator<V>& operator--(); //const const_iterator<V>& operator--(int );
bool operator==(const const_iterator& iter) const;
bool operator!=(const const_iterator& iter) const;
;
Stack();
unsigned int getLength() const;
void push(T data);
T pop();
T getTop() const;
const_iterator begin() const;
const_iterator end() const;
virtual ~Stack();protected:
;
template <typename T>Stack<T>::Stack():top(0), length(0)
;
template <typename T>unsigned int Stack<T>::getLength() const

return length;
;
template <typename T>void Stack<T>::push(T data)

Node *p = new Node;
p->data = data;
p->next = top;
top = p;
++length;
;
template <typename T>T Stack<T>::pop()

Node *p = top;
T data = p->data;
top = top->next;
--length;
delete p;
return data;
;
template <typename T> T Stack<T>::getTop() const

return top->data;
;
template <typename T> typename Stack<T>::const_iterator Stack<T>::begin() const

return const_iterator::const_iterator(top);
;
template <typename T>
typename Stack<T>::const_iterator
Stack<T>::end() const

return const_iterator::const_iterator(0);

template <typename T> Stack<T>::~Stack()

while(length)

pop();


template <typename T> Stack<T>::const_iterator::const_iterator(Node *ptr):p(ptr)

template <typename T>const T& Stack<T>::const_iterator::operator*()
return this->p->data;
template <typename T> typename Stack<T>::const_iterator& Stack<T>::const_iterator::operator++()
p = p->next; return *this;
template <typename T> const typename Stack<T>::const_iterator Stack<T>::const_iterator::operator++(int )
const_iterator tmp = *this; p = p->next; return tmp;//const const_iterator<T>& operator--();//const const_iterator<T>& operator--(int );
template <typename T>bool Stack<T>::const_iterator::operator==(const const_iterator& iter) const
return p == iter.p;
template <typename T>bool Stack<T>::const_iterator::operator!=(const const_iterator& iter) const return !(p == iter.p);

1>正在链接...

1>正在嵌入清单...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0

1>Copyright (C) Microsoft Corporation.  All rights reserved.

1>生成日志保存在“file://c:\\Documents and Settings\\wangwei_b\\My Documents\\Visual Studio 2008\\Projects\\TestMoban\\TestMoban\\Debug\\BuildLog.htm”

1>TestMoban - 0 个错误,1 个警告

========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

追问

  首先,const_itertor不是普通类,即使不用模板参数V,它依然是个类模板,因为它嵌套在类模板内部。如果const_iterator是按照我这样的写法的话,所有的const_iterator的成员函数实现部分有问题,我自己修改过了,但是用gcc 4.8.0,编译的话,const_iterator中重载后置++运算符的那个函数有问题,提示要加typename,但是我加上typename依然不对。

参考技术B

通常, operator自会操作自己的容器, 所以, 你只需要简单的直接用前面的T即可,不需要再定义V.

直接类似下面:


struct Node;
template <typename T>
class Stack
public:
class const_iterator
friend class Stack<T>;
private:
const Node *p;
public:
explicit const_iterator(Node *ptr);
const T& operator*();
;
Stack();
virtual ~Stack();
;

追问

这个我知道,我只是想试试看如果是类模板嵌套的话应该怎么写

参考技术C main函数都没有啊,而且从头看下来太吃力,很多语法错误

模板嵌套类方法的单独定义的正确语法

【中文标题】模板嵌套类方法的单独定义的正确语法【英文标题】:Correct syntax for separate definition of templated nested class methods 【发布时间】:2018-10-24 00:14:03 【问题描述】:

我正在编写一个类,除了作为模板允许不同的数字类型之外,还需要一个额外的嵌套类:

template<typename _type>
class myClass
    // ...
    class myNestedClass
        myNestedClass(int v1, int v2);
        myNestedClass& operator= (std::vector<int> _vals);
        operator std::vector<_type>() const;
        // ...
    
    // ...
    template <typename _input_type> operator*= (_input_type _val);
    // ...

我已经掌握了大部分语法,尤其是在类定义之后如何定义方法:

template <typename _type> 
template <typename _input_type>
myClass<_type>& myClass<_type>::operator*=(_input_type _val) /* */ ;

但我无法为嵌套类方法遵循相同的方案:

template <typename _type> 
myClass<_type>::myNestedClass::myNestedClass(int v1, int v2)  /* */ ;

template <typename _type> 
myClass<_type>::myNestedClass& 
template <typename _type> myClass<_type>::myNestedClass::operator= (std::vector<int> _vals)  /* */ 

template <typename _type> 
myClass<_type>::myNestedClass::operator std::vector<_type> () const  /**/ ;

但是编译器抱怨最后两个方法定义,error: need 'typename' before 'myClass&lt;_type&gt;::myNestedClass' because 'myClass&lt;_type&gt;' is a dependent scope

那么我到底写错了什么?

【问题讨论】:

【参考方案1】:

见When is the "typename" keyword necessary?。

无论如何,你已经很亲近了。修复后(加上一些错别字):

template<typename _type>
class myClass
    // ...
    class myNestedClass
        myNestedClass(int v1, int v2);
        myNestedClass& operator= (std::vector<int> _vals);
        operator std::vector<_type>() const;
        // ...
    ;
    // ...
    template <typename _input_type> myClass<_type>& operator*= (_input_type _val);
    // ...
;

template <typename _type> 
template <typename _input_type>
myClass<_type>& myClass<_type>::operator*=(_input_type _val) /* */ 

template <typename _type>
myClass<_type>::myNestedClass::myNestedClass(int v1, int v2)  /* */ 

template <typename _type> 
typename myClass<_type>::myNestedClass& myClass<_type>::myNestedClass::operator= (std::vector<int> _vals)  /* */ 

template <typename _type> 
myClass<_type>::myNestedClass::operator std::vector<_type> () const  /**/ 

【讨论】:

那么明显吗?我想是调查得太多了,错误消息中说明了答案,但我认为是其他原因造成的。谢谢。

以上是关于C++中,一个类模板的内部又嵌套了一个类模板,语法应该是怎么样的的主要内容,如果未能解决你的问题,请参考以下文章

嵌套模板类方法语法

模板嵌套类方法的单独定义的正确语法

[C++模板] --- 类模板

[C++模板] --- 类模板

对模板类的模糊引用 (C++)

C++模板类的继承