1

以下のコード ブロックでは、リファクタリングしたいので、double のベクトルへの 3 つのポインターの配列を返しています。これを行う最善の方法として、私は少し混乱しています。

エラーがヒットした場合は、呼び出し元の関数から簡単に検出できるようにしたいです。

vCase 変数を次のようなものに変換する必要がありますか?

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

また、これの正しい関数定義は何ですか? 私は配列の基本を理解しています。ネストされたベクトルを持っているという事実は、私を投げるものです!

感謝して受け取った助け。

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

2 に答える 2

2

組み込み配列を返すことはできません。主な理由は、組み込み配列自体はコピーできないためです (組み込み配列は、何かのメンバーである場合はコピー可能です)。最も簡単な方法は、std::array<std::vector<double>, 3>代わりに a を返すことです。

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

インデックスが範囲外の場合は、例外をスローします。もちろん、実際にポインターを返すために使用し、オブジェクトが十分に長く存在する場合は、わずかに変更されたバージョンを使用します。

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

constオプションですが、返されるものは変更されていないかのように聞こえます。

于 2013-09-04T23:44:31.260 に答える
2

あなたが達成したいことが得られるかどうかは本当にわかりません...とにかく、次のことは確かにうまくいきます:

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

ベクトルの配列へのポインターを返したい場合は、次のようにします。

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

delete[]しかし、メモリリークを防ぐために、返されたポインタをどこかで呼び出す必要があるため、これは非常に悪い考えです。より良いオプションは、書くことです

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

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

ポイントは、関数内に一時的なスタック オブジェクトを作成してから、そのオブジェクトへのポインターを返すことはできません。これは、自動的に破棄されるためです。ただし、を使用してオブジェクトを作成する場合はnew、どこかでメモリを解放する必要があり、そのようなコードは記述しません (この場合)。

編集

あなたのコメントから判断すると、次のようなものが必要だと思います。

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

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

この方法では、常に一時オブジェクトを構築する必要はありません。次のように関数を呼び出します。

CaseType myCase;
getCase(myCase);
// do stuff with myCase
于 2013-09-04T23:36:07.433 に答える