具有数据类型的 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 中为 FeatureType1FeatureType2 设置某些类型的占位符类型,然后强制 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 SomeDerivedAnotherDerived 实际上并不具有相同的基础 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> { /* ... */ };