c++ - 处理特定类型元素的任何容器的非模板函数

标签 c++ templates iterator containers

我想要一个如标题中所述的功能。

我注意到,STL 算法适用于包含任何类型(int、double)元素的任何类型(列表、 vector 等)容器,通过使用迭代器类型作为模板参数来提供通用性,例如

template<typename _II, typename _OI>
inline _OI
copy(_II __first, _II __last, _OI __result)

在算法适用于任何类型的元素之前,这是一个很好的方法。元素类型的唯一要求是它必须具有复制构造函数。

但是假设我们有一个具体类型

class MyElement
{
    public:
    void doSomethingWithElement();
};

并且我们希望通过调用函数 doSomethingWithElement() 来实现一个处理此类元素数量的函数。

编写一个接收特定类型容器的函数不是很方便,因为许多容器以相同的方式处理(例如迭代器),如果需要处理不同类型的容器,我们将被迫复制代码。编写模板工作正常,但它看起来很难看,因为我们必须在声明它的地方(在头文件中)实现函数。此外,当我们只想处理一种类型的元素时,将这种类型参数化并不是实现目标的正确方法。

我一直在考虑可以像这样使用的迭代器接口(interface)

void processContainer(IIterator<MyElement> begin, IIterator<MyElement> end);

如果此迭代器具有在派生类中实现的纯虚拟 operator++ 和 operator*,我们可以将此类对象传递给 processContainer。但是有一个问题:如果IIterator是抽象类,我们不能在processContainer的实现中实例化它,如果我们传递一个指针给IIterator,这个函数就可以修改它。

有没有人知道任何其他黑客来做到这一点?或者会是另一种比上述方法更好的方法吗?提前致谢。

最佳答案

更简单的方法是忽略限制,只将函数实现为任何 迭代器的模板。如果迭代器不引用该类型,那么用户将在“type X does not have doSomethingWithElement member function`”行中收到可怕的错误消息。

下一步是提供一个static_assert,该函数仍将采用任何迭代器(意味着它将参与任何类型的重载决策),但错误消息将提供更多信息。

此外,您可以决定使用 SFINAE 来消除候选集中的过载。但是,虽然 SFINAE 是一把漂亮的金锤子,但我不确定您手头是否有合适的钉子。

如果你真的想走得更远,可以看看any_iterator在 Adob​​e 库中,以如何对迭代器类型执行类型删除以避免模板为例。这种方法的复杂性比之前的任何方法都高几个数量级,运行时成本也会更高,唯一的优势是更干净的 ABI 和更小的代码大小(不同的迭代器可以传递给单个函数)。

关于c++ - 处理特定类型元素的任何容器的非模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17280887/

相关文章:

c++ - 从结构数据继承

c++ - QString fromStdString 静态函数而不是构造函数

C++如何将字节读取为独立于整数字节序的?

c++ - 如何构建 Eigen::Map 到我打算用数据填充的 matlab::data::Array 对象

c++ - C++ 模板是否可以(仅)匹配一种类型或一种其他类型的列表?

c++ - operator==() 使用模板模板

c++ - 模板类问题

c++ - 指向指针或引用的迭代器 - 错误

c++ - 为什么 std::distance 不适用于 const 和非 const 迭代器的混合?

actionscript-3 - 通过 AS3 字典进行高效循环