CRTP and dynamic polymorphism compile error
1 2 3 4 5 6 7 8 9 10 11 12 | class A { virtual A* foo() = 0; }; template<class T> class B : public A { virtual T* foo() { return nullptr; } }; class C : public B<C> { }; |
这是一个简化的实现,可以混合复合模式和奇怪的重复模板模式。我得到以下错误:
1 | Return type of virtual function 'foo' is not covariant with the return type of the function it overrides ('C *' is not derived from 'A *') |
在Clang 3.0、GCC 4.7和Visual Studio 2008上测试。
第一解决方案:
1 | class C : public A, public B<C> {} |
在Visual Studio下编译,警告B已经是A的子级,并且不会在出现初始错误的clang下编译。
另一个解决方法:
1 2 | class D : public A {} class C : public B<D> {} |
解决了不完整性问题,但我不知道有多少个实例。直觉告诉我A是虚拟的,所以应该只有一个。
此外,此解决方案还会创建不可读的代码。
关于这种情况,标准规定了什么?这段代码应该编译吗?如果不是,为什么?
虚拟函数
这在理论上是尊重协方差原理的,因为
重新考虑您的设计的一种可能方法是使
1 2 3 4 5 6 7 8 9 | template<typename T> class A { virtual T* foo() = 0; }; template<class T> class B : public A<T> { virtual T* foo() { return nullptr; } }; |
关于您的解决方案:
What does the standard states about this situation? Should this code compile? If not, why?
它不应该编译,因为仅仅使
A class is considered a completely-defined object type (3.9) (or complete type) at the closing
} of the class-specifier.
Within the class member-specification, the class is regarded as complete within function bodies,
default arguments, and brace-or-equal-initializers for non-static data members (including such things in
nested classes). Otherwise it is regarded as incomplete within its own class member-specification.