Ron*_*den 8 c++ gcc templates sizeof
好的,我正在使用g ++ 4.8.2并且有以下(有点长)代码,它获取有关不完整类型的错误消息.我已将代码缩减为较小的块以包含在此处,并且可以直接编译:
#include <cstdlib>
struct S
{
void method(){}
};
template<size_t sz, size_t tot>
class genpool
{
};
template <class T>
class mempool
{
private:
genpool<sizeof(T), 10*sizeof(T)> p;
};
template <class obj, class mthd>
class functor
{
private:
static mempool<functor<obj, mthd> > pool;
};
template <class obj, class mthd>
mempool<functor<obj, mthd> > functor<obj, mthd>::pool;
int main()
{
typedef void (S::*m)();
typedef functor<S, m> fctr;
fctr f;
}
Run Code Online (Sandbox Code Playgroud)
编译器错误消息是:
g++ jj.C
jj.C: In instantiation of ‘class mempool<functor<S, void (S::*)()> >’:
jj.C:30:30: required from ‘class functor<S, void (S::*)()>’
jj.C:37:8: required from here
jj.C:18:17: error: invalid application of ‘sizeof’ to incomplete type ‘functor<S, void (S::*)()>’
genpool<sizeof(T), 10*sizeof(T)> p;
^
Compilation exited abnormally with code 1 at Thu Apr 9 18:50:06
Run Code Online (Sandbox Code Playgroud)
显然,上面定义了模板函子,并且已经明确定义了functor的所有参数.这似乎意味着我应该很好地定义sizeof函数.这里有什么我想念的吗?
--Ron
问题是编译器在实例化mempool<>之前尝试实例化functor<>.这是因为编译器认为它需要能够functor<>::pool在functor<>自身被认为是完全定义之前先定义静态成员.
解决方法是mempool<> &从静态成员函数返回a .
template <class obj, class mthd>
class functor
{
private:
static mempool<functor> & get_pool () {
static mempool<functor> pool;
return pool;
}
};
//template <class obj, class mthd>
//mempool<functor<obj, mthd> > functor<obj, mthd>::pool;
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为引用意味着mempool<>在functor<>实例化之后保持不完整是可以的.(实际上,除非存在实际调用它的代码,否则不会实例化模板的方法.)当调用静态方法时,functor<>本身就是完整的,因此functor<>::get_pool可以正确地实例化其中的静态对象.
作为旁注,将不完整类型作为参数传递给模板是可以接受的,但模板对不完整类型实际执行的操作有限制.如果模板只需要一个引用或指向其实例化类型的指针,那么一切都很好.
我认为你做不到,因为你有一个递归定义。例如,您不能这样做:
#include <cstdlib>
class B;
class A
{
B b;
};
class B
{
A a;
};
int main()
{
A x;
}
Run Code Online (Sandbox Code Playgroud)
唯一的出路是使其中一个成员成为指针而不是实例。