具有前向声明的全班模板专业化

时间:2015-10-27 00:57:05

标签: c++ templates specialization

当在模板类中专门化一些模板函数时,似乎前向声明会导致问题。我正在专门研究这个课程,因为它是为了专门化这个功能所必需的,而这似乎引起了这个问题。

编辑:关于为流程函数预先创建函数的第二个问题:

processor.H

threeLinesBtn.performClick()

processor.C

namespace OM{

template<typename MatchT>  //fwd decl.  ERROR 2. see below.
class Manager;

template<typename MatchT>
class Processor
{
   public:
            Processor(Manager<MatchT>& mgr_):_manager(mgr_) {}
            template<int P>
            void process();

            void doProcess();

   private:
            Manager<MatchT>&   _manager;
            template<int P, int... Ps>
            struct table : table<P-1,P-1, Ps... > {};

            template<int... Ps>
            struct table<0, Ps...>
            {
                static constexpr void(*tns[])() = {process<Ps>...};
            };

            static table<5> _table;
};

}

#include "processor.C"

编译错误:

namespace OM{

#include "MyManager.H" (includes MyManager/MyConfig)
template<typename MatchT>
template<int P>
inline void Processor<MatchT>::process()
{
    ...
    _manager.send();    //this works..
}

template <> template <>
inline void Processor<MyManager<MyConfig> >::process<1>()
{
   _manager.send(); //ERROR 1 - see below.
}

//ERROR here:
template<typename MatchT>
void doProcess()
{
  Processor<MatchT>::_table::tns[2]();  ERROR 3 below.
}

}    

我可以稍微移动一下以确保_manager调用不在专门的函数中,但如果我不需要,我宁愿不这样做。

1 个答案:

答案 0 :(得分:0)

我玩这个,我想现在我得到了类似的结果。

问题是模板专业化和前向声明在一起。这应该是等效的:

template<typename T> struct A;

template<typename T> class B
{
    template<int N>
    T f();
};

template<typename T> class B<A<T>>
{
    A<T> *a;
    template<int N>
    T f();
};

template<typename T> struct A{ T i=1; };//works

template<>
template<>
int B<A<int>>::f<1>()
{
    return a->i + 1;
}

//template<typename T> struct A { T i = 1; };//error

int main()
{
    B<A<int>> b;
}

模板的编译分为两个阶段:

首先,它检查语法和(某些)依赖性。因此,例如,a中的B<A<T>>不是指针/引用,而是对象本身,如果在定义B<A<T>>之后构造A,则可以编译。 (为我工作)

所以第二个是当编译器插入参数时,编译器必须知道所有对象以生成代码。

如上所述,完全专业化时,编译器必须知道所有类型。它已经知道,f函数取决于A的实现,因此它无法生成代码。

因此,您必须在功能专业化之前定义AManager