0

私は次のコード構造を持っています(ResourceそしてParameter空のクラスです):

Solver.cpp

#include "Solver.h"
#include "ValueFunction.h"

using namespace std;

template<typename T>
Solver<T>::Solver(vector<vector<Resource> >& resources, const Parameter& params) : 
    states(resources.size()) {
    for (int i=0; i<resources.size(); i++) {
        states[i] = State<T>(resources[i], params);
    }
}

// Explicit class declaration
template class Solver<ValueFunction>;

Solver.h

#ifndef SOLVER_H_
#define SOLVER_H_

#include <vector>
#include "Resource.h"
#include "Parameter.h"
#include "State.h"

template<typename T>
class Solver {
    public:
        Solver(
            std::vector<std::vector<Resource> >& resources,
            const Parameter& params
        );
    private:
        std::vector<State<T> > states;
};

#endif /* SOLVER_H_ */

状態.cpp

#include "State.h"
#include "ValueFunction.h"

using namespace std;

template<typename T>
State<T>::State(vector<Resource>& _resources, const Parameter& params) : 
resources(_resources), valfuncs(_resources.size(), T(params)) {
}

template class State<ValueFunction>;

State.h

#ifndef STATE_H_
#define STATE_H_

#include <vector>
#include "Parameter.h"
#include "Resource.h"

template<typename T>
class State {
public:
    State() {};
    State(std::vector<Resource>& _resources, const Parameter& params);
    ~State() {};
private:
    std::vector<Resource> resources;
    std::vector<T> valfuncs;
};

#endif /* STATE_H_ */

ValueFunction.cpp

#include "ValueFunction.h"

ValueFunction::ValueFunction(const Parameter& _params) : params(_params) {
}

ValueFunction.h

#ifndef VALUEFUNCTION_H_
#define VALUEFUNCTION_H_

#include "Parameter.h"

class ValueFunction {
public:
    ValueFunction(const Parameter& _params);
private:
    const Parameter& params;
};

#endif /* VALUEFUNCTION_H_ */

次の呼び出しで:

#include "Solver.h"
#include "State.h"
#include "ValueFunction.h"
#include "Parameter.h"

using namespace std;

int main(int argc, char *argv[]) {
Parameter params;
    vector<vector<Resource> > resources(4);
    Solver<ValueFunction> sol(resources, params);
    return 0;
}

そして、次のエラーが表示されます。

Solver.cpp:18:16:   instantiated from here
ValueFunction.h:6:21: error: non-static reference member ‘const Parameter& ValueFunction::params’, can't use default assignment operator

デフォルト以外のコンストラクターを正しく呼び出すにはどうすればよいですか、またはデフォルト以外のコンストラクターで (定数参照を渡す)ValueFunction初期化する他の方法はありますか?std::vector

アップデート

エラーはこの投稿で説明されています。しかし、私の問題の回避策は完全には明らかではありません。助言がありますか?

4

1 に答える 1

4

ベクトル メンバーの既定のコンストラクターを呼び出すコンストラクターの形式を使用して、 をstates初期化しています。Solver2 番目のパラメーターをstatestypeのベクター コンストラクターに渡すState<T>と、ベクターはコピー コンストラクターを使用して、そのパラメーターをソースとして使用するベクター要素を初期化します。コンストラクターのループはSolver、状態ベクトル内で実際に必要な値を提供するために引き続き機能します。

参照は、コンパイラによって生成された既定のコンストラクターによって初期化できません。これは、オブジェクトを初期化するのが既定のコンストラクターの仕事であるためですが、参照には参照するものが必要です。初期化子なしで参照変数を宣言するとエラーが発生するのと同じように、デフォルトのコンストラクターでも同じ問題が発生します。

int &r;      // this is an error
int i;
int &rr = i; // this is proper

コピー コンストラクターは、コピーするオブジェクトの値で参照を初期化するため、ベクター コンストラクターのコピー コンストラクター バージョンを使用すると、問題を回避するのに役立ちます。ベクトルを初期化するこの形式では、 の各要素statesが最初の要素と同じ値に設定されます。

...
    : states(resources.size(), State<T>(resources[0], params))
...

おそらくより良い方法は、ベクター自体にデフォルトのコンストラクターを使用し、 と を使用reservepush_backてベクターに要素を追加することです。State<T>これは、実際にベクターに追加されるまでオブジェクトをまったく作成しないため、より優れています。

...
    : states()
...
    states.reserve(resources.size());
    for (int i...) {
        states.push_back(State<T>(resources[i], params));
    }
...

元のコードが記述されたとおりに機能するようにする 3 番目のアプローチは、メンバーを何か (おそらく恐ろしいグローバル) にValueFunction初期化するための独自の既定のコンストラクターを定義することです。params

class ValueFunction {
public:
    ValueFunction (); // define our own default constructor
    ...
};

const Parameter global_default_parameter;

ValueFunction::ValueFunction () : params(default_parameter) {}
于 2012-06-04T08:54:20.143 に答える