2017-09-24 71 views
0

我有以下功能:功能可能工作就地

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)。在第二種情況下,不應該發生副本。

雖然重載是可以的,但是製作兩個分離的函數並不是一個選項。

+1

有沒有銀在這裏創建一個單獨的函數,它可以在inplace(這可能歸結爲「std :: remove_if」,而不是其他)。 –

+1

*「雖然重載是好的,但是做出兩個分離的函數不是一個選項。」* - 在這裏只是好奇,爲什麼不是一個選項? – WhiZTiM

+1

實現函數的「就地」版本。現在,編寫帶'const'參數的版本。它通過製作第一個參數的副本,然後調用「就地」版本來工作。這是「這個問題的經典解決方案」。 –

回答

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