0
votes

So, I'm creating a class that represents an arbitrarily-sized matrix, and I want to write a function that "exports" the internal Vector to a 2-dimensional array.

I've found some code that seems to do what I want. Here is what the code looks in my class:

// Export matrix to array
double** Matrix::a_data() const
{
    vector<double*> ptrs;
    for (auto& vec : mat) 
    {
        ptrs.push_back(vec.data());
    }
    return ptrs.data();
}

where mat is the vector < vector < double > > used to store the matrix's entries.

The post in question stated that vec needed to be an auto& instead of an auto because it is "very important to prevent vec from being a temporary copy."

However, in Visual Studio I'm always getting an error "no instance of overloaded function push_back matches the argument list... argument types are (const double*)"

So, my question is, how can I get this to work without changing auto& to auto? Also, how would one extend this to 3 dimensions?

1
Bigger problem: ptrs.data() is a dangling pointer as soon as ptrs is destroyed, which happens when a_data() returns. - aschepler

1 Answers

1
votes

You are running into a const problem.

Assuming mat is of type std::vector<std::vector<double>>, vec will be of type std::vector<double> const& in the function. The data() member function for const objects returns const*, not a regular pointer.

Hence, you need to use:

vector<double const*> ptrs;

But then, using

return ptrs.data();

is going to cause bigger problems. ptrs is function local variable. It is going to be destructed when the function returns. Hence, the returned pointer will be a dangling pointer.

Options to overcome that problem.

  1. Change the return type to std::vector<double const*>.
  2. Create a dynamic array of double const** and return it.

I strongly recommend the first option.