4
struct S {
    double arr[1];
    S(double arr[1]) : arr(arr) {}
};

int main(void) {
    double arr[1] = {1.2};
    S p(arr);
    return 0;
}

Hi, this is an extracted problem I encountered in my code.

Do you know why this code won't compile?

main.cpp: In constructor ‘S::S(double*)’:
main.cpp:26:28: error: incompatible types in assignment of ‘double*’ to ‘double [1]’
  S(double arr[1]) : arr(arr) {}

I am using g++, compiling and running with

 g++ -std=c++17 main.cpp kdtree.h kdtree.cpp && ./a.out
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264

4 Answers4

7

Arrays can't be copied.

int a[3];
int b[3];
a = b; // illegal

Further, when you pass an array to a function, its name decays to a pointer, so S(double arr[1]) is equivalent to S(double* arr). Once you're inside the function, you have to copy the individual elements, so you also need the size of the array:

S(double *x, std::size_t sz) {
    std::copy_n(x, sz, arr);
}

You can omit the size if you write the template as a function:

template <std::size_t sz)
S(double (&x)[sz]) {
    std::copy_n(x, sz, arr);
}

Or, even better, use std::array, which works the way you expect.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
6

Do you know why this code won't compile?

It won't compile because arrays cannot be copy-initialized (except copy-list-initialized, but you're not doing that).

Arrays have to be copied one element at a time, using a loop. There's also a standard algorithm for copying so you don't need to write that loop yourself: std::copy.

Or, you can use std::array that was introduced in C++11. std::array is copyable.

eerorika
  • 232,697
  • 12
  • 197
  • 326
3

You can't. What you can do is use the std::array wrapper instead:

struct S {
    std::array<double, 1> arr;
    S(std::array<double, 1> arr) : arr(arr) {}
};
Ron
  • 14,674
  • 4
  • 34
  • 47
3

Although the signature of a constructor is written like that, the array type is adjusted to a pointer, and the array argument decays to a pointer to its first element.

However, the arr member in the struct is still of type array. And a pointer can't be assigned to an array (hence the error).

It's also not possible to assign one array to another (e.g. even if you change it to one of the ways described in the above link), so you need to copy the elements manually with a loop, or using std::copy, or use std::array, as in Ron's answer.

user673679
  • 1,327
  • 1
  • 16
  • 35