8

In the code below, the size of the function (foo) argument (std::vector) can be anything to make the function a generic one. However, sometimes the size container is known so std::array can be used. The problem is to convert the std::array to std::vector. What is the best way to solve this problem? Is it better to just use std::vector always in this case?

#include <iostream>
#include <array>
#include <vector>

using namespace std;

// generic function: size of the container can be anything
void foo (vector<int>& vec)
{
    // do something
}

int main()
{
   array<int,3> arr; // size is known. why use std::vector?
   foo (arr); // cannot convert std::array to std::vector

   return 0;
}
Shibli
  • 5,879
  • 13
  • 62
  • 126
  • 1
    I assume that `foo` modifies the vector since it takes by mutable reference, is that correct? That's going to be very relevant to the answer. – Mooing Duck Jul 22 '14 at 17:49
  • For now you'll have to work around it, but in the future we'll write something like `void foo(RangeOf&);` and it'll take any kind of range of `int`s. – Joseph Mansfield Jul 22 '14 at 17:50
  • 1
    This problem is why the standard library always takes `begin` and `end` iterators. That way it doesn't care which container you use. – Mark Ransom Jul 22 '14 at 17:55
  • 1
    `// size is known. why use std::vector?` -- why **not** use `std::vector`? – David Rodríguez - dribeas Jul 22 '14 at 18:09
  • You could write a wrapper type like [llvm::MutableArrayRef](http://llvm.org/docs/doxygen/html/classllvm_1_1MutableArrayRef.html) – yachoor Jul 22 '14 at 20:01

2 Answers2

16

Given that you pass in an array, foo does not seem to resize the container it gets passed in (however, it does seem to modify the elements since vec is passed non-const). It therefore does not need to know anything about the underlying container other than how to access elements.

Then, you can pass a pair of iterators (and make the iterator type a template argument), as many STL algorithms do.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • Also, If you want to avoid making it a template, the parameters could be a `int* first` and a `size_t count` – Mooing Duck Jul 22 '14 at 17:51
  • 3
    @MooingDuck: `int *begin, int *end` would be C++isher than `int *first, size_t count`. – Nawaz Jul 22 '14 at 17:54
  • Does the STL support the concept of a range? (a pair of iterators), or do I have to manually get begin(), end()? – Michael Mar 16 '18 at 00:17
0

The function accepts a vector by reference. So there is no any sense to pass an object of type std::array to the function. It could have a sense if the parameter of the function would be defined as const reference to a vector.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335