Qt:为模板(地图,列表,集合等)构造一个可变的迭代器 [英] Qt: construct a mutable iterator for template (maps, lists, sets, ...)

查看:61
本文介绍了Qt:为模板(地图,列表,集合等)构造一个可变的迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,我经常具有在不同的可迭代Qt容器类型上执行相同操作的函数,例如:

In my code I often have functions doing the same thing on different iterable Qt Container types, for instance:

void removeX(QMap<qint64, QString> & map)
{
    QMutableMapIterator<qint64, QString> it(map);
    while (it.hasNext()) {
        it.next();
        if (it.value() == "X") it.remove();
    }
}

void removeX(QList<QString> & list)
{
    QMutableListIterator<QString> it(list);
    while (it.hasNext()) {
        it.next();
        if (it.value() == "X") it.remove();
    }
}

(我知道QList中已经有一个removeAll函数.这只是一个愚蠢的最小示例)

(and I know there is already a removeAll function in QList. This is just a silly minimal example)

实际的代码更加复杂,因此引入了很多代码重复.我希望有这样的东西:

The actual code is more complex and hence this introduces a lot of code duplication. I would prefer to have something like:

template <typename T>
void removeX_(T & container)
{
    typename T::mutable_iterator it(container);
    while (it.hasNext()) {
        it.next();
        if (it.value() == "X") it.remove();
    }
}

当然,这不会编译,因为Qt中根本没有":: mutable_iterator"类型定义.一个可以构造一个吗?我看不到这样的简单方法.在这种情况下,"template< ...> getMyMutableIterator"之类的函数将无法正常工作,因为不允许我们为重载的函数返回不同的类型.

Of course, this doesn't compile, as there is simply no "::mutable_iterator" type definition within Qt. Could one construct one? I don't see a easy way to so. A function like "template<...> getMyMutableIterator" can't work in this case, as we are not allowed to return different types for an overloaded function.

但是C ++ 17中有很多新的模板魔术",我还没有真正理解.我可以想象这可能是实现上述代码的简便方法.有没有人在这里减少代码重复的解决方案?

But there is a plenty of new "template magic" from C++17 which I have not really understood yet. I could imagine that it could be a easy way to realize the above code. Has anyone a solution to reduce the code duplication here?

推荐答案

您可以定义特征模板,并部分专门用于相应的容器

You can define a traits template, and partially specialise for the appropriate containers

template <typename Container> struct q_container_traits;

template <typename T> struct q_container_traits<QList<T>>
{
    using mutable_iterator = QMutableListIterator<T>;
    using const_iterator = QListIterator<T>;
};

template <typename Key, typename Value> struct q_container_traits<QMap<Key, Value>>
{
    using mutable_iterator = QMutableMapIterator<Key, Value>;
    using const_iterator = QMapIterator<Key, Value>;
};

// etc

然后在函数中使用q_container_traits<T>.

template <typename T>
void removeX(T & container)
{
    typename q_container_traits<T>::mutable_iterator it(container);
    while (it.hasNext()) {
        it.next();
        if (it.value() == "X") it.remove();
    }
}

这篇关于Qt:为模板(地图,列表,集合等)构造一个可变的迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆