【问题标题】:iterator of a template class and information hiding模板类的迭代器和信息隐藏
【发布时间】:2015-09-06 14:26:39
【问题描述】:
假设我们有一个矩阵模板类的实现。
我希望用T 类型的std::vector 来表示矩阵。
现在,我希望通过返回向量的迭代器来返回矩阵的迭代器。为此,我看到在public 部分中需要使用关键字typename:
typedef typename std::vector<T>::iterator iterator.
首先,我不明白为什么这里需要typename。
第二,大家可以看到我用了std::vector来表示矩阵。
我能做些什么来防止这些信息泄露。
如何在不暴露矩阵表示的情况下实现这个目标?
【问题讨论】:
标签:
c++
templates
iterator
【解决方案2】:
您需要在此处包含typename,因为存在推断类型T。这已被问及回答here。
对于第二个问题,您并没有真正在这里公开类表示;您班级的用户需要了解底层矩阵表示是std::vector 才能使用您的班级。该信息实际上只有在用户努力寻找(例如通过编译错误)时才可用。即使您定义了自己的迭代器,用户仍然可以只查看您的源代码。
最后,如果您使用的是 C++11,做同样事情的更好方法是使用别名:
using iterator = typename std::vector<T>::iterator;
在这种情况下没有立竿见影的优势,但养成这个习惯很好。
【解决方案3】:
首先,我不明白为什么 typename 包含在这里。
typename 告诉编译器iterator 确实是一个类型,而不是一个成员,例如,它们看起来完全一样。在处理模板时,您需要对其进行限定,因为此时编译器通常没有足够的信息来区分。
第二,大家可以看到我用一个向量来表示矩阵,我该怎么做才能防止信息暴露。
虽然每个人都可以看到您使用的是向量,但这并不是商业机密。你提供了一个 typedef 供外部世界使用,强调向量只是一个实现细节,如果他们不这样做,他们应该得到任何东西,在我看来。
为了强调这一点,vector<T>::iterator 也是一个 typedef,在某些编译器中,当您使用不同的标志进行编译时,它意味着不同的东西。有时候你可以查一下,到处使用T*,但是当代码最终崩溃时,你真的会抱怨标准库的开发者吗?
我认为你不能更好地隐藏这一点:编译器需要知道迭代器是什么。