我有以下功能:

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;
    }
}

09-04 17:03
查看更多