2012-04-17 33 views
3

随着C数组,它是相当容易写代码,采取任何大小的数组:std ::数组迭代器范围没有模板?

void func(T* itBegin, T* itEnd); 

void main() { 
    T arr1[1]; 
    func(std::begin(arr1), std::end(arr1)); 
    T arr2[2]; 
    func(std::begin(arr2), std::end(arr2)); 
} 

我如何可以做到这一点的std ::阵列?

void func(??? itBegin, ??? itEnd); 

void main() { 
    std::array<T,1> arr1; 
    func(std::begin(arr1), std::end(arr1)); 
    std::array<T,2> arr2; 
    func(std::begin(arr2), std::end(arr2)); 
} 

的问题是,在2010年MSVC,std::array<T,N>::iterator是不同N不同。这是MSVC 2010中的错误吗?如果不是,这个设计的基本原理是什么?是的,我可以从std ::数组中获取指针并传递它们而不是迭代器,但是这不是不必要的难看吗?

BTW,boost::array<T,N>::iterator对于所有的N都是相同的。

+0

“无模板”是什么意思? – juanchopanza 2012-04-17 10:13:31

+0

'void func(T * itBegin,T * itEnd)'已经是一个模板函数,所以我不能确定你如何遵守那个“没有模板”的要求。 – Gorpik 2012-04-17 10:32:16

+0

@Gorpik:不,它不是模板。它只是使用一个带有不幸名字“T”的类型。参见'main',它也使用'T',不能模板化。 – MSalters 2012-04-17 11:27:17

回答

4
template <class I> 
void func(I begin, I end) 
{ 
    for (auto x = begin; x != end; ++x) 
     something_with(*x); 
} 

通常将它们定义为类型参数,然后就像使用指针一样使用它们。任何类似指针的东西都会编译,而不是的东西不会。

类似指针的东西包括常规指针,以及标准库迭代器以及定义operator=,operator*operator++的其他内容。

这样做,这样,当你将只用一对匹配的开始/结束迭代器相同array<N>范围,那么它并不重要,如果array<N>::iterator是一个不同类型array<M>::iterator

+0

我知道用模板很容易。但是,例如,虚拟函数不能是模板,必须在标题中定义模板。没有必要使用模板的技术原因。 – Arno 2012-04-17 13:06:01

+1

@Arno:类型参数是传递迭代器的C++习惯用法。如果你对模板不满意,你将会使用标准库来痛苦。 – 2012-04-17 14:17:51

0
template <class I> 
void func(I begin, I end); 
2

据我所知道的,标准不要求不同大小的std::array有相同类型的迭代器;具有不同类型的std::array<int, 1>std::array<int, 2>似乎是合法的(尽管对于实施质量可能有一些意见)。

如果这是一个问题,您可以使用C风格的数组,或者使用指针:

func(&arr1[0], &arr1[0] + arr1.size()); 

无论解决方案是理想的,但他们是我能提供的最好。

+0

'&* begin(arr1),&* end(arr1)'?乍一看可能看起来怪异,但应该是一个常用的迭代器技巧,智能指针。 – visitor 2012-04-17 11:18:11

+0

那么,它只适用于底层内存块是连续和紧凑的,这是数组和向量,但当然不是一般的。 – Arno 2012-04-17 14:13:10

+0

@Arno:答案中较长的语法也要求。 – UncleBens 2012-04-17 14:27:18