16

I'm having a brain fart at the moment and I am looking for a fast way to take an array and pass half of it to a function. If I had an array A of ten elements, in some languages I could pass something like A[5:] to the function and be done with it. Is there a similar construct in c++? Obviously I'd like to avoid and sort of looping function.

5
  • 7
    Perhaps your function should take iterators. Commented Nov 27, 2012 at 1:40
  • 1
    You can't pass arrays to functions in C++ because C++ doesn't have array values. So what does your function actually take? Commented Nov 27, 2012 at 1:41
  • I'd have an array int[] a = {1,2,3,4,5,6,7,8,9,10}. I'm then looking for a way to get a sub array int[] a1 = {6,7,8,9,10}. Commented Nov 27, 2012 at 1:45
  • 1
    No, what parameters does your function take? Commented Nov 27, 2012 at 1:47
  • @NicholasHazen, If you really need the array and not iterators, you can still use something like std::vector, which has a dual-iterator constructor: std::vector<int> a{1,2,3,4,5,6,7,8,9,10}; foo(std::vector<int>(std::next(std::begin(a), a.size() / 2), std::end(a))); This strategy really pales in comparison to iterators in terms of speed, however, not to mention easy use. Commented Nov 27, 2012 at 1:47

2 Answers 2

12

Yes. In plain C you use pointers, but in C++ you can use any kind of iterator (a pointer can be considered an iterator).

template<typename Iter>
void func(Iter arr, size_t len) { ... }

int main() {
    int arr[10];
    func(arr, 10);    // whole array
    func(arr, 5);     // first five elements
    func(arr + 5, 5); // last five elements

    std::vector<Thing> vec = ...;
    func(vec.begin(), vec.size());          // All elements
    func(vec.begin(), 5);                   // first five
    func(vec.begin() + 5, vec.size() - 5);  // all but first 5

    return 0;
}

The typical trick is to pass a pointer to the first element of the array, and then use a separate argument to pass the length of the array. Unfortunately there are no bounds checks, so you have to be careful to get it right or you will scribble on your memory.

You can also use half-open ranges. This is the most common way to do it. Many functions in the standard library (like std::sort) work this way.

template<class Iter>
void func(Iter start, Iter end) { ... }

int main() {
    int arr[10];
    func(arr, arr + 10);       // whole array
    func(arr, arr + 5);        // first five elements
    func(arr + 5, arr + 10);   // last five elements

    std::vector<Thing> vec = ...;
    func(vec.begin(), vec.end());       // whole vector
    func(vec.begin(), vec.begin() + 5); // first five elements
    func(vec.begin() + 5, vec.end());   // all but the first five elements

    return 0;
}

Again, no bounds checks.

Sign up to request clarification or add additional context in comments.

4 Comments

I think the templating you were talking about is: template<Iter> void func(const Iter& start, const Iter& end) { ... }
Just template< typename Iter > void func( Iter start, Iter end )
if you want bounds checks use bounds-checked access, &vec.at(5), or vec.begin()+max(5,vec.size()) if '5' is really 'at most 5'.
@jthill: The "max" solution can be problematic because it silently behaves differently, rather than throwing an error. I would usually rather have the error. The "at" solution doesn't give you an iterator, which means you can't pair it with vec.end() but you have to do something like &*vec.end() instead.
4

I also had the same use but instead I used vector and used the syntax

std::vector <int> a(10);
// for example to use by removing first element

a = std::vector<int>(a.begin() + 1, a.end())
//its ur turn to change the size

1 Comment

This vector constructor copies all elements, correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.