场景(参见下面的代码以供参考):
- 原始 (Base) 实现必须让 func1() 返回一个列表。在内部,它调用合并和拼接。
- 后续(派生)实现必须让 func1() 返回一个向量。它需要随机访问。
func2() 对两种实现都是通用的,只需要一个前向迭代器。
#include <iostream> #include <list> #include <vector> class Base { protected: virtual void func1(std::list<int>& l /* out parameter */) { // This must use list. Calls merge and splice. std::cout << "list version of func1 in base\n"; } virtual void func1(std::vector<int>& v) { // This should never be called, but code won't compile without it. std::cout << "vector version of func1 in base\n"; } template <class T> void func2(T container) { typename T::const_iterator it = container.cbegin(); // Iterate and perform work. Common to both Base and Derived. std::cout << "func2 in base\n"; } template <class T> void processHelper() { T container; func1(container); func2<T>(container); } public: virtual void process() { processHelper<std::list<int> >(); } }; class Derived : public Base { protected: virtual void func1(std::vector<int>& v /* out parameter */) { // This must use a random access container. std::cout << "Vector version of func1 in derived\n"; } public: virtual void process() { processHelper<std::vector<int> >(); } }; int main(int argc, const char * argv[]) { std::vector<int> var; Derived der; der.process(); //std::list<int> var; //Base bs; //bs.process(); std::cout << "done\n"; }
目标:
- 没有(或最少)重复(剪切和粘贴)代码。
- 避免使用 Boost 进行编译。(还不需要它。不想这样做。)这排除了几个 any_iterator 实现。
问题:
C++ 中是否有更好的面向对象设计来实现我正在做的事情?在从 func1() 返回之前,我有理由不想将列表转换为向量,反之亦然。具体来说,此时列表很大,我不希望产生额外的副本。我本可以设计 func1() 以返回 opaque_iterator http://www.mr-edd.co.uk/code/opqit,但对引入未知头文件犹豫不决。
无论如何,这个问题具有它自己的学术生命。这个问题在 Java 中很容易,因为集合实现了通用接口,但在 C++ 中似乎具有挑战性。尤其是为了让代码编译而不得不实现 Base::func1(std::vector& v) 的丑陋,即使没有执行路径会调用这个函数。希望有一种更简单的方法,我只是没有看到更直接的解决方案。