joeButler
joeButler

Reputation: 1711

Best way to return pointer to nested std::vector items

In the block of code below I would like to refactor so I'm returning an array of three pointers to a vector of doubles. I'm a little confused as the best way to do this.

If the error is hit, i'd also like it to be easy to detect from the calling function.

Do I need to convert the vCase var into something like:

std::vector<double>[3] vCases
// or
double[3] vCases

Also whats the correct function definition for this? I get the basics of Arrays, the fact i've got a nested vector is whats throwing me!

any help gratefully recieved.

std::vector<std::vector<double> > TrainingCases::getCase(int caseNo) {
    std::vector<std::vector<double> > vCase;
    if (caseNo > vInputs.size()) {
        std::cout << "TrainingCases Error: Out of range caseNo selected. " << std::endl;
        return vCase;
    } else {
        vCase.push_back(vInputs.at(caseNo));
        vCase.push_back(vTargets.at(caseNo));
        vCase.push_back(vScoreModifiers.at(caseNo));
        return vCase;
    }
}

Upvotes: 1

Views: 415

Answers (2)

Rene R.
Rene R.

Reputation: 534

I'm really not sure if I get what you want to accomplish... Anyway, the following would certainly work:

vector<vector<double>> getCase()
{
    vector<vector<double>> vCase;
    return vCase;
}

If you want to kind of return a pointer to an array of vectors, the following would do:

vector<double>* getCase()
{
    vector<double>* vCase = new vector<double>[3];
    return vCase;
}

But that would be a very bad idea, since you would have to call delete[] on the returned pointer somewhere to prevent a memory leak. A better option would be to write

struct CaseType
{
    vector<double> vCase[3];
};

CaseType getCase()
{
    CaseType myCase;
    return myCase;
}

The point is, you cannot create a temporary stack object inside your function and then return a pointer to it, since it will be automatically destructed. If you create the object using new however you will have to free the memory somewhere, and I wouldn't write code like that (in this case).

Edit

Judging from you comment, I believe you want something like this:

struct CaseType
{
    vector<double> vCase[3];
};

void getCase(CaseType& myCase)
{
    // myCase.vCase[0] = ...
    // myCase.vCase[1] = ...
    // ...
}

This way you don't have to construct temporary objects all the time. You would call you function like that:

CaseType myCase;
getCase(myCase);
// do stuff with myCase

Upvotes: 2

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153820

You can't return a built-in array, mainly because they are not copyable when on themselves (built-in arrays are copyable when they are a member of something). The easiest way may be to return a std::array<std::vector<double>, 3> instead:

return std::array<std::vector<double>, 3>{ vInputs[caseNo],
                                           vTargets[caseNo],
                                           vScoreModifiers[caseNo] };

For the case that the index is out of range I would throw an exception. Of course, if you actually use want to return pointers and the objects stay around long enough, you'd use a slightly modified version:

return std::array<std::vector<double> const*, 3>{ &vInputs[caseNo],
                                                  &vTargets[caseNo],
                                                  &vScoreModifiers[caseNo] };

The const is optional but the things you return sound as if they are not getting modified.

Upvotes: 2

Related Questions