即使类型都已定义,模板中的大小也会失败

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

jxh*_*jxh 6

问题是编译器在实例化mempool<>之前尝试实例化functor<>.这是因为编译器认为它需要能够functor<>::poolfunctor<>自身被认为是完全定义之前先定义静态成员.

解决方法是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可以正确地实例化其中的静态对象.

作为旁注,将不完整类型作为参数传递给模板是可以接受的,但模板对不完整类型实际执行的操作有限制.如果模板只需要一个引用或指向其实例化类型的指针,那么一切都很好.


Mar*_*ata 0

我认为你做不到,因为你有一个递归定义。例如,您不能这样做:

#include <cstdlib>

class B;

class A
{
    B b;
};

class B
{
    A a;
};

int main()
{
        A x;
}
Run Code Online (Sandbox Code Playgroud)

唯一的出路是使其中一个成员成为指针而不是实例。