我有以下功能:
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);
在这种情况下,上述实现效果很好。但是,完成了不必要的复制。
问题:这个问题的经典解决方案是什么?
附言我需要两种情况都可以正常工作,在第一种情况下,应该进行复制(我必须接受参数
const
)。在第二种情况下,不应进行任何复制。虽然可以重载,但不能选择两个单独的函数。
最佳答案
通过使用稍微不同的原型,您可以很好地实现您的目标:
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;
}
}