为什么这个CRTP不能编译?

时间:2012-07-23 17:02:57

标签: c++ templates

  

可能重复:
  “Inherited” types using CRTP and typedef

template<typename T>
struct A {
  typename T::Sub  s;
};

struct B : A<B> {
  struct Sub {};
};

Clang报告此错误:

todo.cc:3:15: error: no type named 'Sub' in 'B'
  typename T::Sub  s;
  ~~~~~~~~~~~~^~~
todo.cc:6:12: note: in instantiation of template class 'A<B>' requested here
struct B : A<B> {
           ^

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:2)

B在请求实例化A<B>时是一个不完整的类。

这意味着您只能在B上的模板方法中引用A,因为这些方法的实例化会延迟到B完成。

答案 1 :(得分:1)

由于B继承自A<B>A<B>必须在 B之前构建

由于您使用的是CRTP,这意味着B在构建A<B>时是一个不完整的类。因此,编译器无法判断B是否具有成员字段Sub,因此无法进行编译。

请注意,这次,gcc提供了更有意义的错误:

  

$ cat crtp.cpp

template<typename T>
struct A {
      typename T::Sub  s;
};

struct B : A<B> {
      struct Sub {};
};
  

$ g ++ -c crtp.cpp -o crtp.o

crtp.cpp: In instantiation of ‘A<B>’:
crtp.cpp:6:17:   instantiated from here
crtp.cpp:3:21: error: invalid use of incomplete type ‘struct B’
crtp.cpp:6:8: error: forward declaration of ‘struct B’