2015-10-27 63 views
0

在模板类中专门化某些模板函数时,似乎前向声明引发了一个问题。我也是为了专门化这个功能而专门开发这个类,这似乎是导致这个问题的原因。具有前向声明的完整类模板专业化

编辑:关于处理功能预创建功能,第二个问题:

processor.H

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" 

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. 
} 

}  

编译错误:

1. error: invalid use of incomplete type 'class Manager <MyManager<MyConfig> >' 

2. error: declaration of 'class Manager<MyManager<MyConfig> >' 
    class Manager; 

3. error: no type name '_table' in "class Processor<MyManager<MyConfig> >' 
    I'm not calling this from a specialized function, so I'm not sure 
    why I'm getting this. 

我可以移动一些东西以确保_manager调用不在专用函数内,但是如果我不需要,我宁愿不要。

+0

'namespace OM {.. #include“MyManager.H”'所以当这个头文件被包含时,最终代码中将会包含'namespace OM {namespace OM {'' –

+0

'//这工作..'它可能实际上并没有,它只是没有被实例化。 – user657267

+0

Maanger在同一翻译单元的另一个文件中定义。 – ggs

回答

0

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

问题是模板专门化和前向声明一起。这应该是eqvivalent:

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; 
} 

为模板的编制有两个阶段:

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

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

当完全专门化时,如上所述,编译器被迫知道所有类型。它已经知道,f功能取决于执行A,所以它不能生成代码。

因此,您必须在函数特化之前定义AManager

+0

我明白了......对于我来说,改变文件以便首先定义A是一项工作。我可能会这样做,但现在我已经将呼叫转移到了经理之外的专门功能中。感谢您看这个! – ggs

+0

@ggs我重写了这个例子,现在这应该适合你。欢迎您:) –

+0

谢谢我看到了..我还有一个关于此的问题,但是最好为它另外提一个问题..谢谢。 – ggs