模板类专门化:template-id与任何模板声明都不匹配

时间:2017-07-04 06:50:58

标签: c++ templates template-specialization

我尝试使用模板,但无法理解下面的代码有什么问题。

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是抽象类TNLP的子类。 Ipopt_solve初始化时引用nlp类。

来自main.cpp的

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

我收到如下所示的错误。

错误:template-id&#39; solve&lt;&gt;&#39; for&#39; solve&lt; 1&gt; :: solve(nlp *)&#39;与任何模板声明都不匹配  solve :: solve(nlp * problem):m_ipopt(problem)

2 个答案:

答案 0 :(得分:4)

你应该删除template<>,即

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

template<>用于模板特化(用于模板);但是你只是定义了一个非模板成员函数(类模板特化)。 (这就是编译器抱怨无法找到模板声明的原因。)

答案 1 :(得分:4)

此声明原始形式

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

本身正式有效。但是,它没有做你认为它正在做的事情。此声明声明了主模板 的成员的显式特化

template<int ALG>
class solve
{
  ...

它与您的显式专业化无关

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

编译器正在尝试专门化主模板的构造函数solve<ALG>::solve(nlp* problem) 。但是,主模板没有这样的构造函数。因此,错误消息会告诉您:编译器无法理解您尝试专门化的构造函数,它无法在主模板中找到匹配的成员。

例如,您可以使用此语法显式专门化主模板的默认构造函数

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

这将编译正常,因为主模板确实有这样的构造函数。 (请注意,您不必为此明确地专门化整个类,您可以明确地专门化构造函数。)

显然,您的意图完全不同:在类模板专门化

中提供构造函数的定义
template<>
class solve<IPOPT>
{
  ...

正确的语法不应该提到template<>

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