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还有很多新的"模板魔术",我还没有真正理解.我可以想象它可能是实现上述代码的简单方法.有没有人在这里减少代码重复的解决方案?
您可以定义特征模板,并部分专门用于相应的容器
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)