21

I have this code:

 std::array<int,16> copyarray(int input[16])
{
    std::array<int, 16> result;
    std::copy(std::begin(input), std::end(input), std::begin(result));
    return result;
}

When I try to compile this code, I am getting this error:

'std::begin': no matching overloaded function found 

and a similar error for std::end.

What is the problem and how I can fix it?

7
  • 2
    Size of array parameter does not work this way, it is equal to int *input Commented May 23, 2018 at 13:29
  • @Slava How to fix it? Commented May 23, 2018 at 13:30
  • 9
    Simply don't use C style arrays. They don't know their size and get converted to pointers when used as function parameters. No std::begin overload accepts pointer type. Commented May 23, 2018 at 13:34
  • 2
    @Ron Avoiding arrays might be the intention of the question - possibly there is an array somewhere in code mans cannot change? Commented May 23, 2018 at 13:51
  • 1
    You can also copy between them with std::memcpy( result.data(), input, sizeof(input) ); It might be a good habit to define both array sizes as the same constexpr size_t value. If you retype 16 in multiple places, and they get out of sync, you would have a buffer overflow or underflow. Commented May 23, 2018 at 21:01

3 Answers 3

41

In parameter declaration, int input[16] is same as int* input. And when you pass argument array would decay to pointer, both mean the information about size of the array is lost. And std::begin and std::end can't work with pointers.

You could change it to pass-by-reference, which reserve the array's size.

std::array<int,16> copyarray(int (&input)[16])

Note that you can only pass array with exact size of 16 to the function now.

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

2 Comments

...or use raw pointers (input and input+16) for the algorithm. Of course not recommended, but sometimes one has no other choice
You can even add missing const.
34

Everything important said already, you can get the function just a little bit more flexible:

template <typename T, size_t N>
std::array<T, N> copyarray(T const (&input)[N])
{
    std::array<T, N> result;
    std::copy(std::begin(input), std::end(input), std::begin(result));
    return result;
}

(Late) edit: There is a disadvantage with the approach above: You'll need to copy the returned array on assignment, as it doesn't contain any truely movable data (that's the same for raw arrays already). You can avoid this drawback by directly copying into the target array:

template <typename T, size_t N>
void copyarray(std::array<T, N>& target, T const (&source)[N])
{
    std::copy(std::begin(source), std::end(source), std::begin(target));
}

This mimicks the assignment target = source; if you like better, you can swap the parameters, of course, to have the output parameter last.

Usage (as is):

int source[7] = { };
std::array<int, sizeof(source)/sizeof(*source)> target;
copyarray(target, source);

2 Comments

template <typename T, size_t N> it is from <array> to std::array definition
@UlrichVonRekkenin What are you trying to tell with? Template parameters are the same because they need to be, how else could you have a generic reference to an array? The pattern yet occurs at many other locations, too - have you looked at the std::begin/end variants for arrays, for example?
1

As stated already the problem here is that arrays decay to pointers when passed to a function, meaning that the size is not preserved.

If however you knew that there were 16 elements in the array you could do this:

array<int,16> copyarray(const int input[]) {
    array<int, 16> result;
    copy_n(input, size(result), begin(result));
    return result;
}    

2 Comments

You can preserve size using template<unsigned N> array<int,N> copyarray(const int (&input)[N]) { ... } if you aren't attached to 16. Edit -- Aconcagua parametrized this way but with class T instead of int as well.
@JohnP Yup, just presenting this as an alternative.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.