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 關注
- 689 瀏覽
添加回答
舉報