user8153630
user8153630

Reputation: 301

template class specialization : template-id does not match any template declaration

I'm trying to use templates, but couldn't understand what is wrong with below code.

solve.h

#include "nlp.h"
#include "Ipopt_solve.h"

enum algo_type {IPOPT =1, SQP};

template<int ALG>
class solve
{
public:
    solve()
    {
    }
};

template<>
class solve<IPOPT>
{
public:
    solve(nlp*);

private:
    Ipopt_solve m_ipopt;

};

solve.cpp

template<>
solve<IPOPT>::solve(nlp* problem): m_ipopt(problem)
{
}

Ipopt_solve is a sub-class of an abstract class TNLP. Ipopt_solve is initialized with a reference to nlp class.

from main.cpp

nlp problem(&model);
solve<IPOPT> solution(&problem);

I'm getting the error like shown below.

error: template-id 'solve<>' for 'solve<1>::solve(nlp*)' does not match any template declaration solve::solve(nlp* problem): m_ipopt(problem)

Upvotes: 3

Views: 186

Answers (2)

AnT stands with Russia
AnT stands with Russia

Reputation: 320371

This declaration in its original form

template<>
solve<IPOPT>::solve(nlp* problem): m_ipopt(problem)
{
}

is formally valid by itself. However, it is not doing what you think it is doing. This declaration declares an explicit specialization for a member of the main template

template<int ALG>
class solve
{
  ...

It has no relation to your explicit specialization

template<>
class solve<IPOPT>
{
  ...

The compiler is trying to specialize constructor solve<ALG>::solve(nlp* problem) of the main template. However, the main template has no such constructor. Hence the error message, that tells you exactly that: the compiler does not understand what constructor you are trying to specialize, it cannot find the matching member in the main template.

For example, you can use this syntax to explicitly specialize the default constructor of the main template

template<>
solve<SQP>::solve()
{
  // Specialized code for `solve<SQP>`'s default constructor
}

This will compile fine since the main template does indeed have such constructor. (Note that you don't have to explicitly specialize the whole class for that, you can just explicitly specialize the constructor.)

Your intent was, obviously, completely different: to provide definition for the constructor in the class template specialization

template<>
class solve<IPOPT>
{
  ...

The proper syntax for that should not mention template<>

solve<IPOPT>::solve(nlp* problem): m_ipopt(problem)
{
}

Upvotes: 5

songyuanyao
songyuanyao

Reputation: 172864

You should remove template<>, i.e.

// template <>
solve<IPOPT>::solve(nlp* problem): m_ipopt(problem)
{
}

template<> is used for template specialization (for a template); but you're just defining a non-template member function (of a class template specialization). (That's why the compiler complains that the template declaration can't be found.)

Upvotes: 4

Related Questions