简体   繁体   English

C ++迭代器范围,使用指向数组的指针

[英]C++ Iterator range using pointers to an array

Question

I do not want to pass the size of the array as an index parameter. 我不想将数组的大小作为索引参数传递。

For my merge_sort , I want to optimize my parameters using the iterator range concept. 对于我的merge_sort ,我想使用迭代器范围概念优化参数。 I can't seem to figure out how to deference the iterator range and access my array. 我似乎无法弄清楚如何尊重迭代器范围并访问我的数组。 I can deference to access the indices like low and high in recursive_merge_sort , but there does not seem to be an intuitive way to access the array itself. 我可以尊重访问诸如指数lowhighrecursive_merge_sort ,但似乎并没有被访问阵列本身就是一个直观的方式。 I've been using this great guide on C++ Pointers and Arrays as a starting point. 我一直使用有关C ++指针和数组的出色指南作为起点。

My Merge Sort C++11 C++17 question brought this concept to light and I like the idea of using iterator ranges to reduce the number of parameters for my sort. 我的Merge Sort C ++ 11 C ++ 17问题使这个概念浮出水面,我喜欢使用迭代器范围来减少排序参数数量的想法。

Code

void recursive_merge_sort(int* low, int* high) {
    // deference to get starting index "low" and ending index "high"   
    if(*(low) >= *(high) - 1) { return; }     

    int mid = *(low) + (*(high) - *(low))/2;

    // what's the correct syntax to access my array from the iterator range
    // int* d = some how deference low or how to get the data array they iterate on
    recursive_merge_sort_v(d + low, d + mid);
    recursive_merge_sort_v(d + mid, d + high);
    merge(d + low, mid, d + high);
    // delete d;
}

void merge_sort(int* data) {
    // what's the correct syntax to access my array from the passed in iterator range
    // is this event possible? incorrect syntax below
    recursive_merge_sort(data + 0, data + std::size(*(data)));
}

int main()
{
    int data[] = { 5, 1, 4, 3, 65, 6, 128, 9, 0 };
    int num_elements = std::size(data);

    std::cout << "unsorted\n";
    for(int i=0; i < num_elements; ++i) {
        std::cout << data[i] << " ";
    }

    merge_sort(data);

    std::cout << "\nsorted\n";
    for(int i=0; i < num_elements; ++i) {
        std::cout << data[i] << " ";
    }
}

Comment section Solution from the bayou 评论部分来自bayou的解决方案

Remy Lebeau: "When you pass an array by pointer, you lose all information about it. You can't get back to the original array given only a pointer/iterator, as dereferencing will only give you a single element of the array, not the array itself. When passing an array by pointer, you have no choice but to pass the array size as another parameter. Otherwise, pass the array by reference instead, and if you need to support arrays of different sizes then use a template so the compiler can deduce the array size for the reference." 雷米·勒博(Remy Lebeau):“当您通过指针传递数组时,您将丢失有关该数组的所有信息。仅通过指针/迭代器就无法返回原始数组,因为取消引用只会给您数组的单个元素,而不会给您数组本身。通过指针传递数组时,您别无选择,只能将数组大小作为另一个参数传递;否则,请按引用传递数组,如果需要支持不同大小的数组,请使用模板,因此编译器可以推断出引用的数组大小。”

Iterators are modeled to act like pointers. 迭代器被建模为充当指针。 They have the same type of overloaded operators: dereferencing and increment at the very least (some also have decrement, random access, etc.). 它们具有相同类型的重载运算符:至少要取消引用和递增(某些还具有递减,随机访问等)。

The most advanced iterator interface is random access, which functions exactly like a raw pointer (by design). 最先进的迭代器接口是随机访问,其功能完全类似于原始指针(根据设计)。

So all (raw) pointers are basically random access iterators into a C-style (contiguous) array. 因此,所有(原始)指针基本上都是进入C样式(连续)数组的随机访问迭代器。 Look at the following to visualize begin/end iterators for a C-style array: 查看以下内容以可视化C样式数组的开始/结束迭代器:

int vals[] = { 0, 1, 2, 3, 4 };

int *begin = vals;
int *end   = vals + 5;
v vals[]
0   1   2   3   4   ...
^ begin             ^ end (1 past the end of array)

vals[2] == begin[2]
vals[4] == begin[4]
etc.

So basically, you just treat the begin iterator as the front of the array, and you just don't dereference anywhere before the begin iterator, nor at or past the end iterator, as standard C++ convention dictates the end iterator is 1 past the end of the range. 因此,基本上,您只是将begin迭代器视为数组的前部,并且只是不取消引用begin迭代器之前的任何地方,也不要在结束迭代器的位置或之后进行取消引用,因为标准C ++约定规定end迭代器在末尾是1的范围。

Here's an example of using pointers like iterators: 这是使用迭代器之类的指针的示例:

void print(int *begin, int *end)
{
    // for each element in the range (starting at begin, up to but not including end)
    for (; begin != end; ++begin)
    {
        // print the element
        std::cout << *begin << '\n';
    }
}

int main()
{
    // declare a C-style array
    int arr[] = { 10, 5, 2, 6, 20 };

    // for the sake of example, print only the middle 3 elements
    // begin = arr + 1
    // end   = arr + 4
    print(arr + 1, arr + 4);

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM