繁体   English   中英

C++14:如何将我的模板 function 与 `iterator` 和 `const_iterator` 一起使用

[英]C++14: How can I use my template function with `iterator` and `const_iterator`

所以我有这两个功能应该可以更愉快地检查 map 中是否存在密钥:

template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(const typename Map<K, T>::iterator &it, const Map<K, T> &map) {
    return it == map.end();
}

template<template <typename...> class Map, typename K, typename T>
bool isInMap(const K &key, const Map<K, T> &map) {
    return isEqualToEndOfMap(map.find(key), map);
}

但不幸的是, map.find()返回与std::map::iterator不兼容的std::map::const_iterator 我无法更改为const typename Map<K, T>::const_iterator因为我想将isEqualToEndOfMap与常规迭代器(非 const)一起使用,原因如下:

const auto ret = std::find_if(mmap.begin(), mmap.end(),
                                    [streamShm](const std::pair<int, StreamMapContainer> pair) {
                                        return pair.second.pcktRefShm->id() == streamShm->id();
                                    });
if(isEqualToEndOfMap(ret, mmap))

std::find_if返回常规迭代器,因为map.begin()map.end()正在返回常规迭代器。 当然,铸造是可能的。 但更丑的是:

std::map<int, StreamMapContainer>::const_iterator(..)

几点:

  1. isEqualToEndOfMap不需要通过引用来接受迭代器。
  2. 您可以使用const_iterator作为isEqualToEndOfMap中的参数类型。 类型为iterator的 object 可用于对 function 的调用。
template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(typename Map<K, T>::const_iterator it, const Map<K, T> &map) {
    return it == map.end();
}

这应该适用于您发布的代码中的两个用例。

更新,以回应 OP 的评论。

在评论中,您写道:

但即使便宜,为什么不避免呢?

您必须探索您的选择并决定哪一个最适合您的需求。

除了我已经提出的建议之外,我还能想到另外两个选择。

选项 2

有几个重载,一个用于const_iterator ,一个用于iterator

template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(const typename Map<K, T>::const_iterator &it, const Map<K, T> &map) {
    return it == map.end();
}

template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(const typename Map<K, T>::iterator &it, const Map<K, T> &map) {
    return it == map.end();
}

这并不比第一个选项好,因为您必须维护基本上重复的代码。

选项 3

使用const_iterator&作为参数类型而不是const_iterator

template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(const typename Map<K, T>::const_iterator &it, const Map<K, T> &map) {
    return it == map.end();
}

当使用const_iterator调用 function 时,这会为您保存一份副本,但在使用iterator object 调用时仍需要一个临时 object 副本。

您可能会使用此选项,但它不是惯用的。 迭代器对象的使用几乎与认为它们是指针并按值传递一样。

我的建议是坚持第一个选项。

为什么不是两个模板:

template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(const typename Map<K, T>::iterator &it, const Map<K, T> &map) {
    return it == map.end();
}

和:

template<template <typename...> class Map, typename K, typename T>
bool isEqualToEndOfMap(const typename Map<K, T>::const_iterator &it, const Map<K, T> &map) {
    return it == map.end();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM