如何为模板类调用非默认构造函数?

时间:2012-06-04 08:35:58

标签: c++ templates constructor

我有以下代码结构(ResourceParameter是空类):

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_ */

State.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(传递常量引用)?

更新

post中解释了错误。但我的问题的解决方法并不十分明确。有什么建议吗?

1 个答案:

答案 0 :(得分:4)

您正在使用调用向量成员的默认构造函数的构造函数的形式初始化states Solver。您可以将第二个参数传递给类型为states的{​​{1}}的向量构造函数,向量将使用复制构造函数初始化使用该参数作为源的向量元素。 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)) ... reserve向向量添加元素。这样做更好,因为它可以避免创建任何push_back个对象,直到它实际添加到向量中。

State<T>

第三种允许原始代码按照编写方式工作的方法是为... : states() ... states.reserve(resources.size()); for (int i...) { states.push_back(State<T>(resources[i], params)); } ... 定义自己的默认构造函数,将ValueFunction成员初始化为某些东西(可能是可怕的全局代码) )。

params