1

In the context of creating a hopefully better OO wrapper around the nlopt optimization library where the objective and constraint functions signature and implementation can be defined using Eigen types I have the following problem:

This compiles:

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();

However, this extra line does not compile and gives me the following totally uninformative error:

std::vector<NonLinearConstraint>::const_iterator iter;

error: expected a ";"
     std::vector<NonLinearConstraint>::const_iterator iter;
                                                 ^

btw just in case you are wondering whether I have the correct includes this also compiles:

std::vector<int>::const_iterator iter;

and this also compiles:

inequality_constraints.begin(); // can't assign it to anything without the compiler error

Somehow the compiler doesn't like the NonLinearConstraint template as a vector const iterator but it really doesn't give any hint as to what's wrong.

I don't expect anyone to help me fix the issue here but to give me a pointer how to get more information on this compiler error.

SkyWalker
  • 13,729
  • 18
  • 91
  • 187
  • 1
    Please show a complete example that reproduces the error. Out-of-context lines are not helpful. – n. m. could be an AI Aug 06 '14 at 09:41
  • I of course thought about including something self-contained but it would be too much. I am giving you many examples of what compiles but that line I can't get any information on the error. – SkyWalker Aug 06 '14 at 09:43
  • Let me guess, `ConstraintData` is a template parameter? – T.C. Aug 06 '14 at 09:46
  • 1
    It looks to me like OP is deceiving us. Shouldn't the last two lines be inside the definition of `class NloptSpace`? It doesn't make sense otherwise. – ach Aug 06 '14 at 09:57
  • It is not enough to think about including a self-contained example. It is important to actually include it. Reducing your code to a manageable size could require considerable work, but there's no substitute to that. – n. m. could be an AI Aug 06 '14 at 09:58

1 Answers1

1

std::vector<NonLinearConstraint>::const_iterator is a dependent name - it depends on the template parameter ConstraintData. The standard says that (§14.6 [name.res]/p2):

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.

Therefore, you need to use

  typename std::vector<NonLinearConstraint>::const_iterator iter;
//^^^^^^^^

Otherwise, the compiler considers std::vector<NonLinearConstraint>::const_iterator to not name a type (for all it knows, there can be a specialization of std::vector that defines a member variable called const_iterator).

Modern compilers tend to give better error messages for this, though. g++ 4.8, for instance, produces:

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;
T.C.
  • 133,968
  • 17
  • 288
  • 421