2012-01-11 52 views
1

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

for(VectorBase::size_type i = 0; i < test1.size(); ++i) 

这对于使代码更清洁,不必知道Vector的模板类型(如果它的变化)的优势

for(Vector<int>::size_type i = 0; i < test1.size(); ++i) 

对于我的实现的例子(如果有更好的方法,这里是我如何创建它)。

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

(注意:请不要将它变成“只使用xxx向量类”)。

+1

如果发现你希望你的'size_type'取决于你的模板参数会发生什么? – Grizzly 2012-01-11 18:18:11

+0

我宁愿通过迭代器访问索引访问 - 它更加通用和灵活,除非实际的索引值本身具有某些含义。 – 2012-01-11 18:26:01

+0

@ Grizzly,我不关心我的size_type来自模板参数。它永远都是一样的。 – mmurphy 2012-01-11 18:28:43

回答

1

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

如果你担心容器类型改变,或者:

  1. 为它创建一个typedef,所以test1使用您在循环使用相同类型的名字声明,但类型由该名称代表的将来可以改变。
  2. 编写适当的通用函数,因此容器的类型是模板参数T或其他,并且您使用typename T::size_type作为i的类型。然后如果类型改变,你的代码应付。

    template <typename Container> 
    void print_indexes(const Container &test1) { 
        for (typename Container::size_type i = 0; i < test.size(); ++i) { 
         std::cout << i << '\n'; 
        } 
    } 
    

    替代的解决方法::

    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)实施例:

(1)的实施例

1)只要使用std::size_t。有点作弊,因为原则上我想vector<bool>可以有超过SIZE_MAX元素,但没有“适当”的向量可以比这更大。

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) ... 

我个人倒遵循标准库使用的样式,而不是类型打扰一个容器类模板的公共基类。

+0

另一个人提到了你的第二点,我对它感兴趣。如果我要移除VectorBase,那么将模板设置为“template ”,如何将该类型轻松地公开给用户? – mmurphy 2012-01-11 18:47:24

+0

@mmurphy:通常类似于'template class myvector {public:typedef Type value_type; typedef SizeType size_type; };'。 – 2012-01-11 18:52:39

+0

如何轻松访问size_type值呢?看起来我需要做一些像“Vector :: size_type”(当我的类型是int)时,这部分是我的担心,尽管它可能是它看起来的唯一方式。 – mmurphy 2012-01-11 18:57:08

0

为什么你想重写矢量,当已经有一个完美的一个吗?

如果你确实有从VectorBase继承虽然这将是更好的给VectorBase受保护的析构函数,而不是一个公共虚拟的,因为现在你给了向量的V表。

顺便说一下,您的纯虚拟析构函数的语法不是标准的。

有在保持SIZE_TYPE的typedef的每个载体模板所以就一直在移动它没有很大的优势,没有编译器的开销(即膨胀)。

+0

因为他想要?我想大学习练习。 – Dennis 2012-01-11 18:21:49

+0

@ CashCow,我的最后一行是“(注意:请不要把它变成”只使用xxx矢量类“)。”我的纯虚拟析构函数如何不标准? – mmurphy 2012-01-11 18:31:37

+0

尽管有些编译器允许,但在标准中不允许遵循= 0和{}。 – CashCow 2012-01-12 19:18:20

1

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

通过移动某些部分,以一个共同的基类,你简化了接口,但你也带走一些选择您的模板的派生类或专业领域。

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

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

+0

您提出了一个非常好的观点。因此,如果我要删除VectorBase,那么将模板设置为“template ”,我怎样才能轻松地将该类型暴露给用户? – mmurphy 2012-01-11 18:41:30

+0

std :: vector有一个typedef(类型不是模板参数)。这就允许专业化人员有一个不同的typedef,如果他们想要(不太可能:-))。通过将其设置为模板参数,您可以使用'Vector '和'Vector ',这看起来很灵活。 :-) – 2012-01-11 18:47:52

+0

@Bo:签名大小类型肯定是太灵活了! – 2012-01-11 18:54:28

相关问题