简体   繁体   中英

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)

You should remove template<> , ie

// 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.)

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)
{
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM