关于“模板类作用域内部存在的模板形参推断”的解释

在《C++ primer》第16.4节有如下一段话:

Ordinarily, when we use the name of a class template, we must specify the template parameters. There is one exception to this rule: Inside the scope of the class itself, we may use the unqualified name of the class template. For example, in the declarations of the default and copy constructor the name Queue is a shorthand notation that stands for Queue<Type>. Essentially the compiler infers that when we refer to the name of the class, we are referring to the same version

通常,当使用类模板的名字的时候,必须指定模板形参。这一规则有个例外:在类本身的作用域内部,可以使用类模板的非限定名。例如,在默认构造函数和复制构造函数的声明中,名字 QueueQueue<Type> 缩写表示。实质上,编译器推断,当我们引用类的名字时,引用的是同一版本

这里的“类本身的作用域内部”指的是声明类的一对{}之间的作用域,在类外定义的函数不存在该推断

以下是测试代码:

template <class T>
class CSmartPtr
{
public:
	CSmartPtr(T *t = NULL);							//一般构造函数
	CSmartPtr(const CSmartPtr &rhs);				//拷贝构造函数
	~CSmartPtr();									//析构函数

	CSmartPtr& operator =(const CSmartPtr &rhs)	//复制操作符
	{
		++*rhs.m_piUse;	//防止自身赋值
		rem_ref();		//减少引用计数,检查对象是否应该被销毁
		m_tP = rhs.m_tP;
		m_piUse = rhs.m_piUse;
		return *this;
	}
	T& operator*();									//解引用操作符

	T* operator->();									//调用操作符

	const T& operator*()const; 						//解引用操作符

	const T* operator->()const;						//调用操作符
private:
	T *m_tP;			//被保护的指针
	size_t *m_piUse;	//m_tP所指向的对象被引用的次数
	void rem_ref();		//检查左边指针所拥有的对象是否应该被销毁
};

对于=操作符的重载,如果在类的作用域内部,也就是类声明的一对{}之间定义的话,函数的返回值是可以直接写成CSmartPtr&,不必写完整的CSmartPtr<T>&

但是如果在类外定义=操作符,那么返回值必须写成完整类型的CSmartPtr<T>&:

template <class T>
inline CSmartPtr<T>& CSmartPtr<T>::operator =(const CSmartPtr &rhs)
{
	++*rhs.m_piUse;	//防止自身赋值
	rem_ref();		//减少引用计数,检查对象是否应该被销毁
	m_tP = rhs.m_tP;
	m_piUse = rhs.m_piUse;
	return *this;
}

这里我之所以有疑惑,是对于“类本身的作用域内部”这句话的理解有误,把这个作用域理解成了跟类相关的作用域,包括类外定义的部分了。所以记下来,免得以后犯相同的错误

转载于:https://www.cnblogs.com/chenkunyun/archive/2012/03/18/2404447.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值