在围绕nlopt优化库创建一个有望更好的OO包装的上下文中,目标和约束函数签名和实现可以使用特征类型来定义,我遇到了以下问题:
这编译:
namespace nlopt {
template <class Data>
struct Oracle {
typedef boost::tuple<double, VectorXd> (*f_t) (const VectorXd&, Data& data);
typedef boost::tuple<VectorXd, MatrixXd> (*mf_t)(const VectorXd&, Data& data);
};
};
/// Concrete Nlopt adapter search space implementation.
/**
* Concrete Nlopt adapter search space implementation.
*/
template <class ConstraintData>
class NloptSpace : public ContinuousSpaceInterface<double, VectorXd> {
public:
/// nonlinear constraints
struct NonlinearConstraint {
typename nlopt::Oracle<ConstraintData>::f_t func_; ConstraintData* data_; double tol_;
NonlinearConstraint(typename nlopt::Oracle<ConstraintData>::f_t func, ConstraintData* data, double tol) {
func_ = func;
data_ = data;
tol_ = tol;
}
};
// ...
};
typedef typename NloptSpace<ConstraintData>::NonlinearConstraint NonLinearConstraint;
const std::vector<NonLinearConstraint>& inequality_constraints = space.inequality_constraints();
然而,这额外的一行并没有编译,并且给了我以下完全没有信息的错误:
std::vector<NonLinearConstraint>::const_iterator iter;
error: expected a ";"
std::vector<NonLinearConstraint>::const_iterator iter;
^
顺便说一句,以防万一你想知道我是否有正确的包括这个也编译:
std::vector<int>::const_iterator iter;
这也编译:
inequality_constraints.begin(); // can't assign it to anything without the compiler error
不知怎的,编译器不喜欢NonLinearConstraint
模板作为向量常量迭代器,但它确实没有给出任何错误提示。
我不希望有人帮我解决这个问题,而是给我一个指针,告诉我如何获得有关这个编译器错误的更多信息。
std::vector<NonLinearConstraint>::const_iterator
是一个依赖名称,它依赖于模板参数ConstraintData
。标准规定(§14.6[名称.res]/p2(:
模板声明或定义中使用的名称依赖于模板的参数被假定为不命名类型除非适用的名称查找找到类型名称或名称由关键字CCD_ 4限定。
因此,您需要使用
typename std::vector<NonLinearConstraint>::const_iterator iter;
//^^^^^^^^
否则,编译器认为std::vector<NonLinearConstraint>::const_iterator
不命名类型(据其所知,std::vector
可能有一个专门化,定义了一个名为const_iterator
的成员变量(。
不过,现代编译器倾向于为此提供更好的错误消息。例如,g++4.8产生:
test.cpp:46:2: error: need 'typename' before 'std::vector<typename NloptSpace<ConstraintData>::NonlinearConstraint>::const_iterator' because 'std::vector<typename NloptSpace<ConstraintData>::NonlinearConstraint>' is a dependent scope
std::vector<NonLinearConstraint>::const_iterator iter;
^
test.cpp:46:51: error: expected ';' before 'iter'
std::vector<NonLinearConstraint>::const_iterator iter;