3 回答
TA贡献1111条经验 获得超0个赞
derivedbase在基类列表中将其用作模板参数时,它是不完整的。
常见的解决方法是使用特征类模板。这是您的示例,特征化。这显示了如何通过特征使用派生类中的类型和函数。
// Declare a base_traits traits class template:
template <typename derived_t>
struct base_traits;
// Define the base class that uses the 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));
}
};
// Define the derived class; it can use the traits too:
template <typename T>
struct derived : base<derived<T> > {
typedef typename base_traits<derived>::value_type value_type;
value_type derived_foo() {
return value_type();
}
};
// Declare and define a base_traits specialization for derived:
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用于模板参数derived_t的任何类型,base并确保每个专门化都能提供所需的所有成员base。
TA贡献1809条经验 获得超8个赞
使用特征的一个小缺点是您必须为每个派生类声明一个。您可以像这样编写一个不太冗长和繁琐的解决方法:
template <template <typename> class Derived, typename T>
class base {
public:
typedef T 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(); //return some T object (assumes T is default constructable)
}
};
int main() {
Derived<int> a;
}
TA贡献1864条经验 获得超2个赞
在C ++ 14中,您可以删除typedef和使用函数auto返回类型推导:
template <typename derived_t>
class base {
public:
auto foo() {
return static_cast<derived_t*>(this)->foo();
}
};
之所以可行,是因为将归还类型的推导base::foo延迟到derived_t完成为止。
- 3 回答
- 0 关注
- 646 浏览
添加回答
举报