Qt:为模板构建一个可变迭代器(map,lists,sets,...)

Pat*_*cks 7 c++ qt templates iterator c++17

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

实际代码更复杂,因此引入了大量代码重复.我更喜欢这样的东西:

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

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

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

Cal*_*eth 5

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

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
Run Code Online (Sandbox Code Playgroud)

然后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();
    }
}
Run Code Online (Sandbox Code Playgroud)