C 的强大功能之一,奇怪的循环模板模式 (CRTP),支持静态多态性。这允许编译时灵活地确定基于模板参数创建的对象的类型。然而,扩展 CRTP 以允许基于派生类型修改函数返回类型是一个挑战。
考虑以下尝试泛化 CRTP 的代码:
template <typename derived_t> class base { public: typedef typename derived_t::value_type value_type; value_type foo() { return static_cast<derived_t*>(this)->foo(); } }; template <typename T> class derived : public base<derived<T>> { public: typedef T value_type; value_type foo() { return T(); } };
此代码无法编译Microsoft Visual Studio 2010 由于错误:“value_type”不是以下成员'衍生
该问题源于以下事实:当用作基类列表中的基的模板参数时,衍生是不完整的。为了解决这个问题,常见的解决方法是使用特征类模板。
引入 base_traits 模板:
template <typename derived_t> struct base_traits;
使用特征重新定义基类:
template <typename derived_t> struct base { typedef typename base_traits<derived_t>::value_type value_type; value_type base_foo() { return base_traits<derived_t>::call_foo(static_cast<derived_t*>(this)); } };
并专门化派生的base_traits:
template <typename T> struct base_traits<derived<T> > { typedef T value_type; static value_type call_foo(derived<T>* x) { return x->derived_foo(); } };
这种方法允许通过特征使用派生类的类型和函数。通过为每个模板参数专门化 base_traits,您可以为每个派生类提供所需的成员。
以上是在 C 派生类中使用 CRTP 和 Typedef 时如何解决编译时错误?的详细内容。更多信息请关注PHP中文网其他相关文章!