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下就是不行,只有你回答的最好,就采纳了。
参考技术A1、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.
直接类似下面:
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<_type>::myNestedClass' because 'myClass<_type>' 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++中,一个类模板的内部又嵌套了一个类模板,语法应该是怎么样的的主要内容,如果未能解决你的问题,请参考以下文章