Effective C++ Item 42 了解 typename 的双重意义

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

经验:声明 template 参数时,前缀关键字 class 和 typename 可互换。请使用关键字 typename 标识嵌套从属类型名称;

示例1:

template<typename C>
void print2nd(const C &container){
	C::const_iterator *x;//歧义。如果const_iterator是个static成员变量,x是个global 变量,这里的 *就是乘
	//...
}

示例2:

template<typename C>
void print2nd(const C &container){
		if(container.size() >= 2){
			C::const_iterator iter(container.begin());//这个名称被假设为非类型
		}
}

解析:如果解析器在template中遭遇一个嵌套从属名称,它便假设这名称不是个类型。所以上面的示例不是有效C++代码

纠正:使用关键字 typename 标识嵌套从属类型名称

template<typename C>
void print2nd(const C &container){
	if(container.size() >= 2){
		typename C::const_iterator iter(container.begin());
	}
}

经验:不得在 base class list 或 member initialization list(成员初值列)内以 typename 作为 base class 修饰符

示例:

template<typename T>
class Derived: public Base<T>::Nested{ //其实我觉得,用 typename 是为了让编译器知道嵌套从属类型名称是类型,而这里能用来继承的当然只能是类型了,所以就不用 typename 了
public:
	explicit Derived(int x): Base<T>::Nested(x) // mem.init.list中不允许"typename"
	{
		typename Base<T>::Nested temp; //这里需要 typename
	}
};

Effective C++ Item 42 了解 typename 的双重意义

时间: 2024-08-03 00:45:04

Effective C++ Item 42 了解 typename 的双重意义的相关文章

Effective C++:条款42:了解typename的双重意义

(一) template声明式中,class和typename这两个关键字意义完全相同 template<class T> class Widget; template<typename T> class Widget; (二) template <typename C> void print2nd(const C& container) { if (container.size() >= 2) { C::const_iterator iter(conta

typename的双重意义

<Effective C++> Note 下面有两种template声明: template<class T> class Widget(); template<typename T> class Widget(); 当我们声明template类型参数,class和typename没有什么不同.但是使用typename可以暗示参数并非一定得是个class类型. C++并不总是把class和typename视为等价,有时候你一定得使用typename. 如下这个例子: #

读书笔记 effective c++ Item 47 使用traits class表示类型信息

STL主要由为容器,迭代器和算法创建的模板组成,但是也有一些功能模板.其中之一叫做advance.Advance将一个指定的迭代器移动指定的距离: 1 template<typename IterT, typename DistT> // move iter d units 2 void advance(IterT& iter, DistT d); // forward; if d < 0, 3 // move iter backward 从概念上来说,advance仅仅做了it

读书笔记 effective c++ Item 45 使用成员函数模板来接受“所有兼容类型”

智能指针的行为像是指针,但是没有提供加的功能.例如,Item 13中解释了如何使用标准auto_ptr和tr1::shared_ptr指针在正确的时间自动删除堆上的资源.STL容器中的迭代器基本上都是智能指针:当然,你不能通过使用“++”来将链表中的指向一个节点的内建指针移到下一个节点上去,但是list::iterator可以这么做. 1. 问题分析——如何实现智能指针的隐式转换 真正的指针能够做好的一件事情是支持隐式转换.派生类指针可以隐式转换为基类指针,指向非const的指针可以隐式转换成为

读书笔记 effective c++ Item 38 通过组合(composition)为 “has-a”或者“is-implemented-in-terms-of”建模

1. 什么是组合(composition)? 组合(composition)是一种类型之间的关系,这种关系当一种类型的对象包含另外一种类型的对象时就会产生.举个例子: 1 class Address { ... }; // where someone lives 2 3 class PhoneNumber { ... }; 4 class Person { 5 public: 6 ... 7 private: 8 std::string name; // composed object 9 10

Effective C++ Item 25 考虑写出一个不抛异常的swap函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常 示例: stl里的swap算法 namespace std{ template<typename T> void swap(T &a, T &b){ T temp(a); a = b; b = temp; } } //"pimpl手法"(pointer

Effective C++ Item 48 认识 template 元编程

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:Template metaprogramming (TMP, 模板元编程)可将工作由运行期移往编译期,因而得以实现早期错误侦测和更高的执行效率 示例1: template<typename IterT, typename DistT> void advance(IterT &iter, DistT d){ if(typeid(typename std::iterator_t

Effective C++ Item 44 将与参数无关的代码抽离 templates

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:Templates 生成多个 classes 和多个函数,所以任何 template 代码都不该与某个造成膨胀的 template 参数产生相依关系 因非类型模板参数(non-type template parameters) 而造成的代码膨胀,往往可消除,做法是以函数参数或 class 成员变量替换 template 参数 示例: template<typename T, std:

Effective C++ Item 45 运用成员函数模板接收所有兼容类型

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:请使用 member function templates(成员函数模板)生成"可接受所有兼容类型"的函数 示例:泛化 copy 构造函数 temmplate<typename T> class SmartPtr{ public: template<typename U> SmartPtr(const SmartPtr<U> &o