Error when initialazing struct member array

I have this struct:

template<int N>
struct XYarr
{
    double x[N],y[N];

    int size() {return N;}
};

When I try to intialize it (and return it by a function)

return XYarr<size>{x2, y2}; //x2 and y2 are arrays double[size] 

I get the following error: cannot initialize an array element of type 'double' with an lvalue of type 'double [200]'. What is the problem?

Upvotes: 0

Views: 69

Answers (2)

Vasilij
Vasilij

Reputation: 1941

Compiler can't use member aggregate initialization because C-arrays can't be copied.

To overcome this, provide a constructor for your struct:

template<int N>
struct XYarr
{
    XYarr() = default; // default constructor if needed
    XYarr(const double (&x_)[N], const double (&y_)[N]) {
        memcpy(&x,x_,sizeof (double)*N);
        memcpy(&y,y_,sizeof (double)*N);
    }
    double x[N],y[N];

    int size() {return N;}
};

int main(int argc, char * argv[]) {
    XYarr<100> a; // default constructor
    double x2[100], y2[100];
    auto n = XYarr<100>{x2, y2}; // init constructor

    return 0;
}

There is an std::array version for comparison. std::array can be used with member aggregate initialization - so no boilerplate code, everything is simple.

template<int N>
struct XYarr_stl
{
    std::array<double,N> x,y;
    int size() {return N;}
};

int main(int argc, char * argv[]) {

    std::array<double,100> x2_stl, y2_stl;
    auto n_stl = XYarr_stl<100>{x2_stl, y2_stl};

    // this will give compilation error, because array sizes will be checked at compile time
    //std::array<double,200> x2_stl2, y2_stl2;
    //auto n_stl2 = XYarr_stl2<100>{x2_stl2, y2_stl2};

    return 0;
}

Upvotes: 2

rustyx
rustyx

Reputation: 85341

Raw arrays don't have value semantics. Thus they can't be initialized or assigned using the = operator and need to be copied explicitly. For example, using a constructor like this:

#include <algorithm>

template<int N>
struct XYarr
{
    double x[N], y[N];

    XYarr(const double(&x2)[N], const double(&y2)[N]) {
        std::copy(std::begin(x2), std::end(x2), x);
        std::copy(std::begin(y2), std::end(y2), y);
    }

    int size() const { return N; }
};
int main() {
    double x2[4]{}, y2[4]{};
    XYarr<4> test{ x2, y2 };
}

Upvotes: 3

Related Questions