C++模板与继承

b.b*_*old 7 c++ inheritance templates code-complexity

我只是意识到提出问题是多么困难......希望我能给出两个都足够精确的例子来展示我的问题,并且足够短以免弄乱一切......至少可以编辑.

所以这就是我目前的情况.当然,我在逻辑/结构(以及无论如何命名方面)方面对它进行了一些修改,试图关注我问题的本质:

// MyClass deals with lists (actually several data structures) of the
// type MyType which should support different types and has to be 
// efficiently dealt with. Templating seems just right here
class MyClass
{
  ...

  void doSomething<class MyType>(vector<MyType> someList);

  ...

  // At some point I have to extract elements of the type MyType.
  // The extractor obviously depends on MyType but it is not possible to
  // Create a general version that could use templates itself 
  // (unless I use a specialization for each possible MyType)

  // I am stuck between these two alternatives:

  // Possibility1:
  // Let the client pass the right extractor and template it.
  template<class Extractor, class MyType>
  void extract(const Extractor& extractor, const string& source, 
               vector<MyType>* dest)
  {
     extractor.extract(source, dest);
  }

  // Possibility2:
  // Use a member _extractor of some base type that has to be set
  // to a specialization. The ExtractorBase has a virtual method
  // template<T> void extract(const string& source, vector<T>* myType) = 0
  // with no definition that is only defined in subclasses wrt certain
  // postings.
  ExtractorBase _extractor;

  template<class MyType>
  void extract(const string& source, vector<MyType>* dest)
  {
     _extractor.extract(source, dest);
  }
}
Run Code Online (Sandbox Code Playgroud)

目前我更喜欢的可能性1,因为我不需要在Extractor中使用MyType的所有变体以及我希望将来尝试的相关Extractor的继承.

另一方面,提取器可能需要复杂的代码和几个成员(类似于映射特定值的某些输入的巨大地图).因此,使用模板不会带来性能提升.特别是使用头文件只有Extractors,甚至可能是内联的仿函数,都是不可能的.在过去,这一直是我的一个强有力的指针,模板化只会增加代码复杂性(必须处理实例化,使客户端代码的生活变得更加困难等),我应该尽量避免使用它.

或者我有没有想到的第三种可能性?

iam*_*ind 2

最好选择第一个选项。它更干净且可维护。

因为从您的评论中,我发现您对第二个选项做出了错误的假设:

// The ExtractorBase has a virtual method
// template<T> void extract(const string& source, vector<T>* myType) = 0;
Run Code Online (Sandbox Code Playgroud)

。那是不可能的;函数template永远不可能是virtual。因此,要实现第二个选项,您必须选择一些肮脏且难以维护的方法,这不是一个好主意。