Suppose I have a struct SignalError which has an element "errName" and many other elements:
typedef struct SignalError
{
QString errName;
.....
};
I create QList of this struct:
QList<SignalError> signalErrList;
I will append the struct element to the QList using append call.
SignalError sgErr1 = {"Error_1"};
signalerrList.append(sgErr1);
Before appending the element to the list I want to check if there is any element with the same name "errName" already existing in the QList or not. If it is then I will not add the element to the list. How do I do this?
Also, should I create a list of objects like:
QList<SignalError> signalErrList;
or create list of pointer to the object:
QList<SignalError*> signalErrList;
CodePudding user response:
You should use QList<SignalError> signalErrList;
not a QList
of pointers.
If you don’t care about order, you should use a std::set<SignalError>
which will give you deduplication automatically.
If you care about order and the O(N) search isn’t a problem, then use QList
or std::vector
and do
if (auto it = std::find(signalErrList.begin(), signalErrList.end(), sgErr1;
it == signalErrList.end()) {
signalErrList.push_back(std::move(sgErr1));
}
which you could (and should) name as a function:
//! A linear-time (O(n)) search followed by push-back if not found
//! API modeled on https://en.cppreference.com/w/cpp/container/set/emplace
template <typename Container, typename Value>
std::pair<typename Container::iterator, bool>
emplaceBackLinearUnique(Container& c, Value&& v) {
if (auto it = std::find(c.begin(), c.end(), v); it != c.end()) {
// Return iterator to the found one and say that it wasn't emplaced.
return { it, false };
}
// Not found:
c.emplace_back(std::forward<Value>(v));
// Return iterator to the new last element and report that it was emplaced:
return { c.begin() c.size() - 1, true };
}
which lets you replace. your use case with this.:
emplaceBackLinearUnique(signalErrList, sgErr1);