我有一個具有非常相似的重復代碼的函式。我喜歡重構它,但不想要任何復雜的映射代碼。該代碼基本上過濾掉表中的列。我通過讓比較陳述句具有簡單型別使這個示例變得簡單,但真正的比較可能更復雜。我希望可能有一些模板或 lambda 技術可以做到這一點。
if (rec->field2 != *field2)
vector<MyRecord*>& MyDb::Find(bool* field1, std::string* field2, int* field3)
{
std::vector<MyRecord*>::iterator iter;
filterList_.clear();
std::copy(list_.begin(), list_.end(), back_inserter(filterList_));
if (field1)
{
iter = filterList_.begin();
while (iter != filterList_.end())
{
MyRecord* rec = *iter;
if (rec->field1 != *field1)
{
filterList_.erase(iter);
continue;
}
iter ;
}
}
if (field2)
{
iter = filterList_.begin();
while (iter != filterList_.end())
{
MyRecord* rec = *iter;
if (rec->field2 != *field2)
{
filterList_.erase(iter);
continue;
}
iter ;
}
}
if (field3)
{
iter = filterList_.begin();
while (iter != filterList_.end())
{
MyRecord* rec = *iter;
if (rec->field3 != *field3)
{
filterList_.erase(iter);
continue;
}
iter ;
}
}
return filterList_;
}
以防萬一有人好奇,這是我的最終代碼。再次感謝大家。很容易理解和維護。
vector<MyRecord*>& MyDb::Find(bool* field1, std::string* field2, int* field3)
{
auto compare = [&](MyRecord* rec) {
bool add = true;
if (field1 && rec->field1 != *field1) {
add = false;
}
if (field2 && rec->field2 != *field2) {
add = false;
}
if (field3 && rec->field3 != *field3) {
add = false;
}
return add;
};
filterList_.clear();
std::copy_if(list_.begin(), list_.end(), back_inserter(filterList_), compare);
return filterList_;
}
uj5u.com熱心網友回復:
你可以使用std::copy_if(因為你已經/無論如何都會做一個副本)
vector<MyRecord*>& MyDb::Find(bool* field1, std::string* field2, int* field3){
filterList_.clear();
std::copy_if(list_.begin(), list_.end(), back_inserter(filterList_),[&](MyRecord* rec){
// whatever condition you want.
return field3 && rec->field3 != *field3;
});
return filterList_;
}
uj5u.com熱心網友回復:
有沒有一種簡單的方法來重構這段代碼?
據我了解您的演算法/意圖,使用std::erase_if(c 20)您可以按如下方式替換整個while回圈(演示代碼):
#include <vector> // std::erase_if
std::vector<MyRecord*> // return by copy as filterList_ is local to function scope
Find(bool* field1 = nullptr, std::string* field2 = nullptr, int* field3 = nullptr)
{
std::vector<MyRecord*> filterList_{ list_ }; // copy of original
const auto erased = std::erase_if(filterList_, [=](MyRecord* record) {
return record
&& ((field1 && record->field1 != *field1)
|| (field2 && record->field2 != *field2)
|| (field3 && record->field3 != *field3));
}
);
return filterList_;
}
如果不支持 C 20,或者您可以使用erase–remove idiom,這實際上發生在std::erase_if.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/515156.html
標籤:C 模板
