创建模板化矢量类时,允许使用其大小类型的最佳方法是什么?从我收集的内容来看,似乎是要创建一个真正的矢量类接口,然后使用它。如
for(VectorBase::size_type i = 0; i < test1.size(); ++i)
这比
更有优势for(Vector<int>::size_type i = 0; i < test1.size(); ++i)
使代码更清晰,无需知道Vector的模板类型(如果它发生了变化)。
关于我的实现示例(如果有更好的方法,这就是我创建它的方式)。
class VectorBase
{
public:
typedef unsigned int size_type;
protected:
size_type mCount;
public:
VectorBase() { mCount = 2; }
virtual ~VectorBase() = 0 { }
size_type size() const { return mCount; }
};
template<typename Type>
class Vector : public VectorBase
{
public:
Vector() : VectorBase() { }
~Vector() { }
};
int main(void)
{
Vector<int> test1;
for(VectorBase::size_type i = 0; i < test1.size(); ++i)
{
cout << i << endl;
}
system("PAUSE");
return(0);
}
(注意:请不要把它变成&#34;只需使用xxx矢量类。&#34;)。
答案 0 :(得分:1)
我不认为有最好的方法。 : - )
通过将某些部分移动到公共基类,可以简化界面,但是您也会删除模板的派生类或特化的一些选择。
例如,vector<char>
可能需要long long
大小类型,如果您希望它包含大量字符。 vector<my_huge_type>
的潜在专业化可能只需要int
?
我们应该事先决定unsigned int总是足够好吗?也许,也许不是。设计一个界面,如果经常在复杂性和灵活性之间找到一个很好的平衡点。
答案 1 :(得分:1)
无需知道Vector的模板类型(如果它发生变化)。
如果您担心容器类型发生变化,请:
test1
,但该名称所代表的类型将来可能会更改。T
或其他,您使用typename T::size_type
作为i
的类型。然后,如果类型发生变化,您的代码就会出现问题。(1)的例子:
typedef vector<int> test_type;
test_type test1;
// populate the vector
for (test_type::size_type i = 0; i < test1.size(); ++i) std::cout << i << '\n';
(2)的例子:
template <typename Container>
void print_indexes(const Container &test1) {
for (typename Container::size_type i = 0; i < test.size(); ++i) {
std::cout << i << '\n';
}
}
替代解决方法:
1)只需使用std::size_t
即可。稍微作弊,因为原则上我认为vector<bool>
可以有超过SIZE_MAX
个元素,但没有&#34;正确的&#34;矢量可以比那更大。
2)(仅限C ++ 11)使用auto
作为i
的类型
for (auto i = test.size(); i != 0; --i) std::cout << (test.size() - i) << '\n';
或
for (decltype(test.size()) i = 0; i < test1.size(); ++i) ...
就我个人而言,我遵循标准库中使用的样式,而不是为容器类模板的公共基类而烦恼。
答案 2 :(得分:0)
为什么要在已经有一个非常好的Vector时重写Vector?
如果你确实必须从VectorBase继承,虽然最好给VectorBase一个受保护的析构函数而不是公共虚函数,现在你给了Vector一个v-table。
顺便提一下,纯虚析构函数的语法不是标准的。
在每个向量模板中保持size_type的typedef没有编译器开销(即膨胀),因此移动它没有太大的优势。