关于使用template时的错误注意

今天在写c++程序的时候,在使用template时遇到了一个关于template的错误用法。代码如下
#include 
#include 
#include 
#include 
#include 
using namespace std;
template 
void print_elem(const list &container){
    //auto const_point = container.cbegin(); 对,自动推断当前第一个元素的迭代器类型
    //list::const_iterator const_point = container.cbegin(); 对,但是这样写的缺点是当类型不一致的时候需要经常修改数据类型
    //const int *const_point = container.cbegin(); erro,因为这是一个指向容器中第一个元素的迭代器
    typename list::const_iterator const_point = container.cbegin();//不能少了typename,否则编译器不知道当前的是什么类型
    for(;const_point!=container.cend(); ++const_point){
        cout<<*const_point<<" ";
    }
    cout< linkint {10,20,30,40};
    print_elem(linkint);
}
上面是我的测试代码,问题出现在下面的代码,原因是我使用了模板函数造成的
auto const_point = container.cbegin(); //对,自动推断当前指针的类型
list::const_iterator const_point = container.cbegin(); //对,但是这样写的缺点是当类型不一致的时候需要经常修改数据类型
const int *const_point = container.cbegin(); //erro,因为这是一个指向容器的指针
typename list::const_iterator const_point = container.cbegin();//不能少了typename,否则编译器不知道当前的是什么类型

上面的写法中,第三种是很明显的错误,原因是当前的形参是一个容器,所以使用container.cbegin()返回的是一个指向容器中第一个元素的迭代器,但是如果使用int*去接的话很明显出错,即使是加了const类型的指针,所以从这个角度来看,迭代器和指针差不多,但是从根本上来说,有本质的区别。

除过第三种的错误写法以外,第一种写法自由,可以让编译器自己判定当前的迭代器类型;第二种的话也可以,但是这是因为我知道自己要传递 int 类型的数据,所以比较麻烦。同时还需要注意,由于list本身是const类型,需要使用const型的iterator才行,也就是list::const_iterator,否则就会报错,而与形参print_elem(const list &container)中是否有const没有根本关系;

对于最后一种,一定要在list::const_iterator const_point = container.cbegin()前使用typename,如果没有就会发生下面的错误:

error: need 'typename' before 'std::__cxx11::list::const_iterator' because 'std::__cxx11::list' is a dependent scope
      list::const_iterator const_point = container.cbegin();

也即编译器当前的是什么类型的名称,但是在类中不需要使用typename,如果不是类中,而是在函数中,则要一定使用typename自动推断当前的类型名称

你可能感兴趣的:(C++,c++)