Reputation: 23
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
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
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