Код: Выделить всё
TTThreadSafeMapКод: Выделить всё
const_iteratorКод: Выделить всё
template
class TRADETOOLS_EXPORT TTThreadSafeMap
{
protected:
mutable QReadWriteLock lock;
QMap data;
public:
class const_iterator
{
private:
TTReadWriteLocker locker;
const QMap *data; // Pointer to the underlying data
typename QMap::const_iterator it;
friend TTThreadSafeMap;
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = W;
using difference_type = std::ptrdiff_t;
using pointer = const W*;
using reference = const W&;
public:
const_iterator(QReadWriteLock *lock, const QMap &data, typename QMap::const_iterator start) : data(&data), it(start)
{
if(lock)
locker.reset(lock, LockType::READ);
}
// Equality operator
bool operator==(const const_iterator &other) const
{
return this->it == other.it;
}
// Inequality operator
bool operator!=(const const_iterator &other) const
{
return this->it != other.it;
}
// Increment operator (pre-increment)
const_iterator & operator++(void)
{
if(!this->data || this->it == this->data->cend()) // Crashes on this comparison
return *this;
// Unexecuted code here
}
};
// Begin iterator
const_iterator cbegin(const bool obtainLock = true) const
{
TTReadWriteLocker locker;
if(obtainLock)
locker.reset(&this->lock, LockType::READ);
return const_iterator(obtainLock ? &this->lock : Q_NULLPTR, this->data, this->data.cbegin());
}
};
Код: Выделить всё
TTReadWriteLocker::TTReadWriteLocker(QReadWriteLock *lock, const LockType lockType, const qint64 timeoutMS) : lock(lock), timeoutMS(timeoutMS), lockType(lockType)
{
this->obtainLock();
}
TTReadWriteLocker::TTReadWriteLocker(TTReadWriteLocker &&other) noexcept
{
*this = std::move(other);
}
TTReadWriteLocker::~TTReadWriteLocker(void)
{
this->releaseLock();
}
QReadWriteLock * TTReadWriteLocker::getLock(void) const noexcept
{
return this->lock;
}
void TTReadWriteLocker::obtainLock(void)
{
if(!this->lock)
return;
if(this->lockType == LockType::READ)
{
if(!this->lock->tryLockForRead(this->timeoutMS))
throw TTException(ERROR_TEXT(LOCATION, "Lock failed (read): see which lock and debug the blocking location"));
}
else if(this->lockType == LockType::WRITE)
{
if(!this->lock->tryLockForWrite(this->timeoutMS))
throw TTException(ERROR_TEXT(LOCATION, "Lock failed (write): see which lock and debug the blocking location"));
}
else
throw TTException(ERROR_TEXT(LOCATION, "Invalid LockType: LockType::NOT_SET"));
}
void TTReadWriteLocker::releaseLock(void)
{
if(this->lock)
this->lock->unlock();
}
void TTReadWriteLocker::reset(QReadWriteLock *lock, const LockType lockType)
{
this->releaseLock();
this->lock = lock;
this->lockType = lockType;
this->obtainLock();
}
TTReadWriteLocker & TTReadWriteLocker::operator=(TTReadWriteLocker &&other) noexcept
{
this->lock = std::move(other.lock);
this->timeoutMS = std::move(other.timeoutMS);
this->lockType = std::move(other.lockType);
other.lock = Q_NULLPTR;
other.lockType = LockType::NOT_SET;
return *this;
}
Код: Выделить всё
barsКод: Выделить всё
for(TTThreadSafeMap::const_iterator itBar=bar->cbegin(),endBar=bar->cend(); itBar!=endBar; ++itBar)
{
// Do some stuff
}
< /code>
Цикл входит, делает кое -что, затем пытается увеличить итератор. При сравнении this-> it == this-> data-> cend () Код: Выделить всё
TTThreadSafeMap::dataРасположение Я в недоумении за то, почему возникает ошибка. Следующая функция, проверка функциональности, работает нормально: < /p>
Код: Выделить всё
void testThreadSafeMap(void)
{
QSharedPointer bars = QSharedPointer::create();
QSharedPointer bars2 = Q_NULLPTR;
TTThreadSafeMap::const_iterator itBar,endBar,tBar;
QSharedPointer bar1(new Bar), bar2(new Bar), bar3(new Bar);
bar1->timestamp = 1;
bar2->timestamp = 2;
bar3->timestamp = 3;
bars->insert(bar1->timestamp, bar1);
bars->insert(bar2->timestamp, bar2);
bars->insert(bar3->timestamp, bar3);
itBar=bars->cbegin();
endBar=bars->cend();
tBar = bars->cfind(2);
bars2 = bars->sharedCopy(true,false);
for(; itBar!=endBar; ++itBar)
{
qDebug() timestamp;
}
}
У меня есть аналогичная версия, обертывающая QVector, которая работает без проблем (в нескольких потоках).
Версия Qt: 6.8.1
Версия C++: 20
Сможете ли вы увидеть недостаток, которого не вижу я? Есть ли какие-нибудь направления в этом направлении? Заранее спасибо.
Подробнее здесь: https://stackoverflow.com/questions/793 ... comparison
Мобильная версия