当在模板类中专门化一些模板函数时,似乎前向声明会导致问题。我正在专门研究这个课程,因为它是为了专门化这个功能所必需的,而这似乎引起了这个问题。
编辑:关于为流程函数预先创建函数的第二个问题:
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调用不在专门的函数中,但如果我不需要,我宁愿不这样做。
答案 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
的实现,因此它无法生成代码。
因此,您必须在功能专业化之前定义A
或Manager
。