具有数据类型的 C++ 抽象基础将在派生 class 中定义
c++ abstract base with datatype will be defined in derived class
我想要一个基础 class,其数据类型将在派生 class 中定义。
伪代码
class Base{
public:
void Enroll(vector<int> v){
feature_list.emplace_back(ExtractFeature1(v));
}
vector<double> Compare(vector<int> v){
FeatureType2 ft2 = ExtractFeature2(v);
vector<double> scores;
for (auto &ft1:feature_list){
scores.emplace_back(Compare(ft1, ft2));
}
return scores;
}
protected:
vector<FeatureType1> feature_list;
virtual FeatureType1 ExtractFeature1(vector<int> v)=0;
virtual FeatureType2 ExtractFeature2(vector<int> v)=0;
virtual double Compare(FeatureType1 f1,FeatureType2 f2)=0;
}
因此每个派生的 class 将实现不同的提取和比较特征的方式。
我不知道如何在 Base
class 中为 FeatureType1
和 FeatureType2
设置某些类型的占位符类型,然后强制 Derived
class 来定义它们。任何建议或指导将不胜感激。
I want to have a base class with datatypes that will be defined in derived class.
嗯,你不能完全那样做:必须完全定义基础 class 才能从中派生 classes。
但是,您可以使用 Curiously-Recurring Template Pattern (CRTP):
template <typename T>
class Base {
using data_type = typename T::data_type;
// this will be a different type for each T - and
// we don't need to know it in advance
void Enroll(const vector<int>& v){
// implementation that can depend on T in many ways.
// Specifically, you can use `data_type`.
}
vector<double> Compare(const vector<int>& v){ /* ... */ }
// ...
};
class SomeDerived : Base<SomeDerived> { /* ... */ };
class AnotherDerived : Base<AnotherDerived> { /* ... */ };
classes SomeDerived
和 AnotherDerived
实际上并不具有相同的基础 class,但它们的基础 classes 是相同的模板,因此您可以避免代码重复。并且 - 你有 "base" class 使用派生 class 中定义的类型,只要它们以相同的方式定义。
编辑(感谢@Aconcagua):您可能不需要达到完整的 CRTP。如果你的基础 class 唯一需要知道关于派生 class 的是数据类型,那么只需在 that 上模板化基础 class,即
template <typename DataType>
class Base {
using data_type = DataType;
// ... as before...
};
class SomeDerived : Base<some_data_type> { /* ... */ };
class AnotherDerived : Base<another_data_type> { /* ... */ };
我想要一个基础 class,其数据类型将在派生 class 中定义。
伪代码
class Base{
public:
void Enroll(vector<int> v){
feature_list.emplace_back(ExtractFeature1(v));
}
vector<double> Compare(vector<int> v){
FeatureType2 ft2 = ExtractFeature2(v);
vector<double> scores;
for (auto &ft1:feature_list){
scores.emplace_back(Compare(ft1, ft2));
}
return scores;
}
protected:
vector<FeatureType1> feature_list;
virtual FeatureType1 ExtractFeature1(vector<int> v)=0;
virtual FeatureType2 ExtractFeature2(vector<int> v)=0;
virtual double Compare(FeatureType1 f1,FeatureType2 f2)=0;
}
因此每个派生的 class 将实现不同的提取和比较特征的方式。
我不知道如何在 Base
class 中为 FeatureType1
和 FeatureType2
设置某些类型的占位符类型,然后强制 Derived
class 来定义它们。任何建议或指导将不胜感激。
I want to have a base class with datatypes that will be defined in derived class.
嗯,你不能完全那样做:必须完全定义基础 class 才能从中派生 classes。
但是,您可以使用 Curiously-Recurring Template Pattern (CRTP):
template <typename T>
class Base {
using data_type = typename T::data_type;
// this will be a different type for each T - and
// we don't need to know it in advance
void Enroll(const vector<int>& v){
// implementation that can depend on T in many ways.
// Specifically, you can use `data_type`.
}
vector<double> Compare(const vector<int>& v){ /* ... */ }
// ...
};
class SomeDerived : Base<SomeDerived> { /* ... */ };
class AnotherDerived : Base<AnotherDerived> { /* ... */ };
classes SomeDerived
和 AnotherDerived
实际上并不具有相同的基础 class,但它们的基础 classes 是相同的模板,因此您可以避免代码重复。并且 - 你有 "base" class 使用派生 class 中定义的类型,只要它们以相同的方式定义。
编辑(感谢@Aconcagua):您可能不需要达到完整的 CRTP。如果你的基础 class 唯一需要知道关于派生 class 的是数据类型,那么只需在 that 上模板化基础 class,即
template <typename DataType>
class Base {
using data_type = DataType;
// ... as before...
};
class SomeDerived : Base<some_data_type> { /* ... */ };
class AnotherDerived : Base<another_data_type> { /* ... */ };