0

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?

6
  • This question needs more info, what's the code surrounding that return? in particular can you give us the signature of the function where it is called? Commented Aug 13, 2020 at 13:01
  • 1
    Use std::array<double, N> instead. Arrays can't be copied implicitly. The error message sounds like it is related to copying an array. Commented Aug 13, 2020 at 13:01
  • Function signature is as follows: template<int size> XYarr<size> sortSplitted(double x[], double y[]). Commented Aug 13, 2020 at 13:04
  • 1
    @MartinVítVavřík Please read about minimal reproducible example and edit your question accordingly. Put new information in the question directly. Commented Aug 13, 2020 at 13:07
  • 1
    @MartinVítVavřík That is an interesting preference, as std::array is generally considered to be strictly superior to C-style arrays. The problem here isn't entirely clear yet, but if it is related to assigning an array to try to copy it, you would need to std::copy each element instead. Commented Aug 13, 2020 at 13:09

2 Answers 2

3

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 };
}
Sign up to request clarification or add additional context in comments.

Comments

2

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.