C++中的关键字typename
来源:互联网 发布:apache base64 jar 编辑:程序博客网 时间:2024/05/16 17:03
近来想做对LIST的更方便使用的模板类,头文件如下:
#include "config.hpp"
namespace System
{
namespace Collections
{
template<class ValueType>
class List
{
public:
List();
virtual ~List();
virtual int Add(ValueType value);
virtual bool Contains(ValueType value);
virtual void Delete(int index);
virtual ValueType GetByIndex(int index);
virtual int GetCount();
virtual void Insert(int index, ValueType value);
virtual void InsertAfter(ValueType item, ValueType value);
virtual void InsertBefore(ValueType item, ValueType value);
virtual void Update(int index, ValueType value);
virtual shared_ptr<ValueType> Prev(ValueType value);
virtual shared_ptr<ValueType> Next(ValueType value);
private:
shared_ptr<list<ValueType> > items;
};
}
}
实现文件如下:
#include "List.hpp"
using System::Collections::List;
template<class ValueType>
List<ValueType>::List()
{
items = new shared_ptr<list<ValueType> >;
}
template<class ValueType>
List<ValueType>::~List()
{}
.
.
.
template<class ValueType>
void List<ValueType>::InsertAfter(ValueType item, ValueType value)
{
if(!items)
{
throw new shared_ptr<exception>(new exception("items hadn't been initialized!"));
}
//程序编译时提示这儿会出错:提示信息为expect ';' before itemiterator
if((items::iterator itemiterator = find(items.begin(),items.end(),item)) != items.end())
items.insert(itemiterator,value);
.
.
.
后来检查全部代码,发现没有什么错误,后来到网上搜索到,应该在声明itemiterator时,在前面加上C++关键字:typename
改后的代码如下:
typename list<ValueType>::iterator itemiterator;
itemiterator = find(items.begin(),items.end(),item);
if(itemiterator != items.end())
items.insert(itemiterator,value);
}
.
.
.
看来还是自己对C++不熟悉,于是从箱子底下翻出了N久以前的<<C++ Template>>
解释如下:
"
关键字typename是C++标准化过程中被引入的,目的在于向编译器说明template内的某个标识符是类型(而不是其它什么东西),考虑下面的例子:
template <typename T>
class MyClass{
typename T::SubType * ptr;
...
};
在这里,第二个typename关键字的意思是:SubType是class T内部定义的一个类型,因此ptr是一个指向T::SubType类型的指针。
如果没有使用关键字typename,SubType会被认为是class T的一个static成员,于是被编译器理解为一个具体变量,从而导致以下表达式:
T::SubType * ptr
所表达的意义变成:class T的static成员SubType与ptr的乘积。
注:Visual C++ 6.0/ICL 7.1/G++ 3.2在上述的MyClass被实例化之前,都假设SubType是成员类型,因此认为上述例子是正确的,Visual C++ 7.1认为这是错误的(Visual C++ 7.1 对类型要求极其严格),然而当具体实例化时,如果SubType不是一个成员类型,四个编译器都会报错。
通常如果某个与template parameter相关的名称是个类型的时候,你就必须加上关键字typename。更详细的讨论见<<C++ Template>> p130
typename的一个典型应用是在template程序代码中使用STL容器提供的迭代器(iterators):
//basic/printcoll.hpp
#include <iostream>
//print elements in a STL container
template <typename T>
void printcoll(T const& coll)
{
typename T::const_iterator pos;
typename T::const_iterator end(coll.end());
for (pos = coll.begin();pos != end;++pos)
{
std::cout << *pos << '';
}
std::cout << std::endl;
}
在这个function template中,coll是个STL容器,其元素类型为T。这里使用了STL容器的迭代器类型(iterator type)循环访问coll的所有元素,迭代器类型为const_iterator,每一个STL容器都有这种类型:
class stlcontainer {
...
typedef ... iterator; //可读写迭代器
typedef ... const_iterator; //只读迭代器
...
};
使用template type T的const_iterator时,你必须写出全名,并在最前面加上关键字typename:
typename T::const_iterator pos;
.template构造函数
引入关键字typename之后,又出现了一个类似的问题,考虑下面的程序代码,其中使用标准的bitset类型:
template<int N>
void printBitset(std::bitset<N> const& bs)
{
std::cout << bs.template to_string<char,char_traits<char>,allocator<char> >();
}
注:
/* 你也可以充分利用bitset的member typedef 像下面这样:
std::cout << bs.template to_string<std::string::value_type,
std::string::traits_type,
std::string::allocator_type>();*/
此例中的.template看起来有点儿怪,但是如果没有它,编译器无法知道紧跟其后的 "<" 代表的是template argument list的起始,而非是一个小于符号,注意,只有当位于“.”之前的构造取决于某个template parameter时,这个问题才会发生。以上例子中,参数bs便是取决于template parameter N.
结论是“.template”或“->template”标记只有在templates之内才能被使用,而且他们必须紧跟着“与template parameters相关的”。
"
我的编程环境:Ubuntu G++ boost-1_34_1
- C++中的关键字typename
- C++中的typename关键字
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字
- STL中的typename与class关键字
- C++ Template 中的typename、class关键字区别
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字
- C++ Template 中的typename、class关键字区别
- 关键字typename
- typename关键字
- typename关键字
- c++模板中的 typename 和 template 关键字用法
- typedef和typename关键字
- 夕食の後のレギュラーエクスプレスについての議論(1)
- tomcat 配置域名
- 数据绑定Eval方法vs.Bind方法
- 黑洞2007自定义协议版本 演示穿越卡巴6和ZA防火墙
- 关闭窗口事件
- C++中的关键字typename
- 在weblogic环境中,通过连接池访问数据库
- 为什么黑洞远程控制的屏幕传输比Radmin快
- OSWorkflow基本概念
- 开始Python -- List和Tuple(3)
- js,获取当前的时间
- .NET开发平台
- XMLHTTPRequest简介
- oracle 将A用户权限赋给B用户