我有以下功能:
shared_ptr_of_points filter(const shared_ptr_of_points input){
shared_ptr_of_points result = make_new();
for(const auto item:input->points){
if(cond(item)){
result->add_point(item);
}
}
return result;
}
典型用途是:
auto filtered_points = filter(some_noisy_points);
但是,它可能以另一种方式使用:
some_points = filter(some_points);
在这种情况下,上述实现工作正常。但是,完成了不必要的复制。
问题:这个问题的经典解决方案是什么?
P.S。我需要两种情况都能正常工作,在第一种情况下,副本应该发生(我必须接受参数const
)。在第二种情况下,不应发生任何副本。
虽然重载是可以的,但是不能选择两个独立的函数。
答案 0 :(得分:2)
通过使用略有不同的原型,您可以很好地实现目标:
void filter(const shared_ptr_of_points & input, shared_ptr_of_points & output)
如果您愿意使用它,那么可能的实现将如下所示:
// Example program
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <algorithm>
typedef std::shared_ptr<std::vector<int>> shared_ptr_of_points;
bool cond(int x){
return x > 100;
}
void filterCopy(const shared_ptr_of_points & input, shared_ptr_of_points & output){
if (!output){
output = std::make_shared<std::vector<int>>();
}
for(const auto item:*input){
if(cond(item)){
output->push_back(item);
}
}
}
void filterInplace(shared_ptr_of_points & inout){
inout->erase(std::remove_if(inout->begin(), inout->end(), [](int x){return !cond(x);}), inout->end());
}
void filter(const shared_ptr_of_points & input, shared_ptr_of_points & output){
if (output == input)
filterInplace(output);
else
filterCopy(input, output);
}
int main()
{
shared_ptr_of_points pts = std::make_shared<std::vector<int>>();
pts->emplace_back(100);
pts->emplace_back(200);
pts->emplace_back(300);
for(const auto item:*pts){
std::cout << item << std::endl;
}
std::cout << "**********" << std::endl;
shared_ptr_of_points resCopy;
filter(pts, resCopy);
for(const auto item:*resCopy){
std::cout << item << std::endl;
}
std::cout << "**********" << std::endl;
filter(pts, pts);
for(const auto item:*pts){
std::cout << item << std::endl;
}
}