《c++ Templates》笔记 第五章 技巧性基础知识

关键字typename

如果要访问依赖模板参数的类型名称,要在类型名称前添加关键字typename

class Type
{
    class SubType
    {
        
    }
}

template<typename T>
class MyClass
{
    typename T::SubType* ptr;  // typename声明SubType是定义于类T内部的一种类型
    T::SubType* ptr; // 不使用typename,T::SubType表示T中的静态成员。表示乘法操作
    ...
}
使用this->

如果基类是类模版,不能直接调用基类的成员,必须用this->去调用

template<typename T>
class Base
{
public:
	void exit1()
	{
		std::cout << "call Base::exit1()." << std::endl;
	}
};

void exit1()
{
	std::cout << "call exit1()." << std::endl;
}

template<typename T>
class Derived : public Base<T>
{
public:
	void foo()
	{
		exit1();			// call exit1().
		this->exit1();      // call Base::exit1().
        Base<T>::exit1();	// call Base::exit1().
	}
};
成员模板

嵌套类和成员函数也可以是模板

template<typename T>
class Stack
{
private:
    std::deque<T> elemes;
public:
	template<typename T2>
    Stack<T>& operator=(Stack<T2> const&);
}

template<typename T>
template<typename T2>
Stack<T>& Stack<T>::operator=(Stack<T2> const& op2)
{
    if((void*)this == (void*)&op2){
        return *this;
    }
    
    Stack<T2> temp(op2);
    elems.clear();
    while(!temp.empty()){
        elems.push_front(temp.top());
        temp.pop();
    }
    return *this;
}
模板的模板参数
// typename T1 = allocator<T>> class CONT是模板参数,但它也是一个模板,缺省值是std::deque模板,CONT和缺省值std::deque两个模板的模板参数必须完全匹配。
template<typename T, template<typename ELEM, typename T1 = allocator<ELEM>> class CONT = std::deque>
class Stack
{
    CONT<T> elems;
}
零初始化

任何未被初始化的局部变量都具有一个不确定的(undefined)值。

模板参数的初始化方式:

template<typename T>
class MyClass
{
    T x;
    MyClass(): x(){}	// 初始化方法1
    void foo()
    {
        x = T();  // 初始化方法2
    }
}

对于内建类型,比如int,bool等,也可以采用这种方法初始化。

这两种初始化方式是通用的,指针也可以这样初始化,初始化为0。

使用字符串作用函数模板的实参

字符常量的类型为const char[]。比如“name”的类型为const char[5],5 = 4个字符 + 一个’\0’。

const char[4]和const char[5]是不同的类型,它门占用的内存大小不相同。

// 使用引用时,字符串常量模板实参为其本身,即字符常量数组const char[]
template<typename T>
inline T const& max(T const& a, T const& b)
{
	return a < b ? b : a;    
}

string s;
::max("apple", "peach");  // OK:相同类型的实参,都为const char[6]
::max("apple", "tomato"); // ERROR:不同类型的实参,const char[6], const char[7]
::max("apple", s);        // ERROR:不同类型的实参,const char[6], string

========================================================================================

// 不使用引用时,字符串常量作为参数会退化成const char*指针
template<typename T>
inline T max(T a, T b)
{
	return a < b ? b : a;    
}

string s;
::max("apple", "peach");  // OK:相同类型的实参,都为const char*
::max("apple", "tomato"); // OK:相同类型的实参,都为const char*
::max("apple", s);        // ERROR:不同类型的实参,const char*, string
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值