使用虚函数和C++继承机制与使用模板和boost概念之间的关系是什么?
似乎可能的重叠很多.也就是说,似乎可以用任何一种方法实现多态行为.那么,何时支持一个而不是另一个呢?
我提出这个问题的原因是因为我有一个模板化容器,容器本身具有层次关系.我想编写使用这些容器的算法,而不关心它是哪个特定的容器.此外,一些算法将受益于知道模板类型满足某些概念(例如,可比较).
所以,一方面,我希望容器具有多态性.另一方面,如果我想正确实现某些算法,我仍然需要使用概念.什么是初级开发人员?
我认为概念是一种元界面.他们按照自己的能力对类型进行分类.下一个C++版本提供本机概念.直到我遇到C++ 1x的概念以及它们如何允许将不同但不相关的类型组合在一起时,我才理解它.想象一下,你有一个Range
界面.您可以通过两种方式对其进行建模.一个是子类型关系:
class Range { virtual Iterator * begin() = 0; virtual Iterator * end() = 0; virtual size_t size() = 0; };
当然,每个派生的类都实现了Range接口,并且可以与您的函数一起使用.但是现在你看到它是有限的.阵列怎么样?这也是一个范围!
T t[N]; begin() => t end() => t + size() size() => N
遗憾的是,您无法从实现该接口的Range类派生数组.你需要一个额外的方法(重载).那么第三方容器呢?您的库的用户可能希望将他们的容器与您的功能一起使用.但他无法改变其容器的定义.在这里,概念进入游戏:
auto concept Range{ typename iterator; iterator T::begin(); iterator T::end(); size_t T::size(); }
现在,您说一些类型的支持操作,如果T
具有适当的成员函数,则可以实现.在您的库中,您将编写泛型函数.这允许您接受任何类型,只要它支持所需的操作:
templatevoid assign(R const& r) { ... iterate from r.begin() to r.end(). }
这是一种很好的可替代性.任何类型都符合遵守概念的法案,而不仅仅是那些积极实施某些界面的类型.下一个C++标准更进一步:它定义了一个Container
概念,它将适用于普通数组(通过一些caled 概念图定义一些类型如何适合某些概念)和其他现有标准容器.
我提出这个问题的原因是因为我有一个模板化容器,容器本身具有层次关系.我想编写使用这些容器的算法,而不关心它是哪个特定的容器.此外,一些算法将受益于知道模板类型满足某些概念(例如,可比较).
实际上你可以用模板做两件事.您可以继续使用层次关系来共享代码,然后以通用方式编写算法.例如,传达您的容器具有可比性.这类似于标准的随机访问/转发/输出/输入迭代器类别:
// tag types for the comparator cagetory struct not_comparable { }; struct basic_comparable : not_comparable { }; templateclass MyVector : public BasicContainer { typedef basic_comparable comparator_kind; }; /* Container concept */ T::comparator_kind: comparator category
实际上,这是一种合理的简单方法.现在您可以调用一个函数,它将转发到正确的实现.
templatevoid takesAdvantage(Container const& c) { takesAdvantageOfCompare(c, typename Container::comparator_kind()); } // implementation for basic_comparable containers template void takesAdvantage(Container const& c, basic_comparable) { ... } // implementation for not_comparable containers template void takesAdvantage(Container const& c, not_comparable) { ... }
实际上可以使用不同的技术来实现它.另一种方法是boost::enable_if
每次使用启用或禁用不同的实现.