1 typename关键字
什么时候使用typename?
最常见的是template < typename T>模板参数;其次当某个依赖于模板参数的名称是一个类型时,需要用typename来修饰。eg:
template <typename T>
class A
{
typename T::subtype* ptr; // 指向T::subtype类型的指针
}
先看看如果不使用typename,T::subtype * ptr; 应该理解:
使用到::,那subtype是T类型下的一个静态成员,那么理解起来就是成员A * ptr;明显和我们的意图不符合,这里subtype是依赖T的一个类型,对应上面的粗体文字,我们知道ptr是一个某某类型的一个对象指针(依赖模板的一个类型)。
进一步讲,如果在typename前面加个typedef typename T::subtype* ptr; 这时就是别名了。
2 .template构造
如果某个对象是依赖于模板参数时,需要使用到.template 或是->template来标记,这些标记只能用在模板中。
template <int N>
void print(const std::bitset<N>& bs)
{
std::cout <<
bs.template to_string<char, char_traits<char>, allocator<char>>();
}
.template, 可以这么理解. 和-> 是前面对象的引用符号,后面的template是用来修饰后面的<>的。
bs的类型是依赖于模板参数N,正好符合上面的条件。
3 使用this->
对于有基类的类模板,如果基类有fun()成员函数,在派生类中掉哦那个fun()时,必须要用this->或是Base< T >::来指定:我们调用的是基类的成员,如果不指定,那么func()调用的就是外部函数,或是报错
经测试(vs2015sp3),发现对于成员变量,如果派生类不加this->就会报错,如果是成员函数,都会走基类的实现,这点和书上说的不一样,还需要多测试
好吧,刚才群里的大神指点了迷津:
http://codepad.org/
http://melpon.org/wandbox
一个是用来共享testcase,一个是在线编译,也可以共享url的。
通过这两个网址,终于将问题和群里的大神共享了,在第二个网站上验证了,发现书上写的都是正确的。
对于依赖模板参数的符号(不管是函数还是变量),都应该使用this->或是base< T >::来指定,避免不确定性。
在这一定要喷一下vs2015sp3,已经打算换到linux下。
- 零初始化
意思是,就算是内置类型,任何未初始化的局部变量都是一个不确定的值 - 字符串作为模板参数时,容易引起意外的结果
总结:
如果要访问依赖模板参数的类型名称,应该在类型名称前面加上typename
嵌套类和成员函数也可以试模板
赋值运算符的模板版本并没有取代缺省赋值运算符
类模板也可以作为模板参数。这成为模板的模板参数
模板的模板实参需要精确匹配
对于模板中的局部变量(就算是内置类型),都需要显示调用缺省的构造函数,以确保变量都被初始化了。这个对于成员变量也适用
对于字符串,在实参推导过程中,当且仅当参数不是引用时,才会出现数组到指针的类型转换