使用通用矢量大小类型的最佳方法是什么?

时间:2012-01-11 18:12:02

标签: c++ algorithm templates vector

创建模板化矢量类时,允许使用其大小类型的最佳方法是什么?从我收集的内容来看,似乎是要创建一个真正的矢量类接口,然后使用它。如

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;)。

3 个答案:

答案 0 :(得分:1)

我不认为有最好的方法。 : - )

通过将某些部分移动到公共基类,可以简化界面,但是您也会删除模板的派生类或特化的一些选择。

例如,vector<char>可能需要long long大小类型,如果您希望它包含大量字符。 vector<my_huge_type>的潜在专业化可能只需要int

我们应该事先决定unsigned int总是足够好吗?也许,也许不是。设计一个界面,如果经常在复杂性和灵活性之间找到一个很好的平衡点。

答案 1 :(得分:1)

  

无需知道Vector的模板类型(如果它发生变化)。

如果您担心容器类型发生变化,请:

  1. 为它创建一个typedef,因此使用您在循环中使用的相同类型名称声明test1,但该名称所代表的类型将来可能会更改。
  2. 编写正确的通用函数,因此容器的类型是模板参数T或其他,您使用typename T::size_type作为i的类型。然后,如果类型发生变化,您的代码就会出现问题。
  3. (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没有编译器开销(即膨胀),因此移动它没有太大的优势。