2012-01-26 23 views
2

我試圖在模板上應用stl算法remove_if,並遇到了一些麻煩。任何幫助表示讚賞!C++ STL算法remove_if與模板一起使用

template <class T> bool flag_delete(pair<T,int> a) {return (a.second == 1);} 

template <class T> void fun_delete_by_flag(vector<T> &vec_data, ivec &vec_flag) 
{ 
    int n = vec_data.size(); 
    vector< pair<T,int> > vec; 
    vec.resize(n); 
    for (int i = 0; i < n; i += 1) { 
     vec[i].first = vec_data[i]; 
     vec[i].second = vec_flag[i]; 
    } 
    typename vector< pair<T,int> >::iterator it; 
    it = remove_if(vec.begin(), vec.end(), flag_delete); 
    n = vec.size(); 
    vec_data.resize(n); 
    for (int i = 0; i < n; i += 1) { 
     vec_data[i] = vec[i].first; 
    } 
    return; 
} 

我得到了以下信息:

guess_algo.h: In function ‘void fun_delete_by_flag(std::vector<T>&, ivec&) [with T = std::pair<int, std::basic_string<char> >, ivec = std::vector<int>]’: 
user_time.h:63:34: instantiated from here 
guess_algo.h:61:2: error: no matching function for call to ‘remove_if(std::vector<std::pair<std::pair<int, std::basic_string<char> >, int>, std::allocator<std::pair<std::pair<int, std::basic_string<char> >, int> > >::iterator, std::vector<std::pair<std::pair<int, std::basic_string<char> >, int>, std::allocator<std::pair<std::pair<int, std::basic_string<char> >, int> > >::iterator, <unresolved overloaded function type>)’ 

回答

3

你需要改變你的remove_if調用如下:

it = remove_if(vec.begin(), vec.end(), flag_delete<T>); 

即。在flag_delete的末尾添加<T>,因爲您尚未告知該函數應該具有與fun_delete_by_flag相同的模板參數。這裏的提示是錯誤消息結尾處的(相當好的隱藏)<unresolved overloaded function type>

0

嘗試一下錯誤信息第一行:

guess_algo.h: In function ‘void fun_delete_by_flag(std::vector<T>&, ivec&) [with T = std::pair<int, std::basic_string<char> >, ivec = std::vector<int>]’: 

那告訴你,T是類型對。最後一行告訴你(最後)你正在調用「未解析的重載函數類型」。這意味着,你給它的參數不同於函數flag_delete中定義的參數。

從第一個錯誤消息,你給它配對。嘗試檢查你的類型,也許,將T改爲另一個字符。

3

無論他人提出什麼問題(需要特定的模板參數),您都錯過了對std::vector::erase(或vec_data.resize()調用是多餘的)的調用。

std::remove_if確實不是減小容器的尺寸!

所以,要麼添加了標記線

auto it = remove_if(vec.begin(), vec.end(), flag_delete<T>); 
vec.erase(it);  // <-- ADD THIS TO ACTUALLY REDUCE CONTAINER LENGTH 
n = vec.size(); 
vec_data.resize(n); 

或重寫它一下。明知矢量分配是連續的按照標準,你可以在整個濃縮成(假設的C++ 0x的支持):

template <class T> void simpler(vector<T> &vec_data, const ivec &vec_flag) 
{ 
    T *begin = &vec_data.front(); 
    size_t newsize = std::distance(begin, 
      std::remove_if(
       begin, begin + vec_data.size(), [&] (T& el) 
       { 
        return 1 == vec_flag[std::distance(begin, &el)]; 
       })); 

    vec_data.resize(newsize); 
} 

親身體驗:http://ideone.com/S2WUC

編輯我已經清理了原有的功能了有點太(注意const&size_terasereservestd::make_pair):

template <class T> void fun_delete_by_flag(vector<T> &vec_data, const ivec &vec_flag) 
{ 
    size_t n = vec_data.size(); 
    vector< pair<T,int> > vec; 
    vec.reserve(n); 
    for (size_t i = 0; i < n; i += 1) 
     vec.push_back(std::make_pair(vec_data[i], vec_flag[i])); 

    vec.erase(remove_if(vec.begin(), vec.end(), flag_delete<T>)); 

    n = vec.size(); 
    vec_data.resize(n); 

    for (size_t i = 0; i < n; i += 1) 
     vec_data[i] = vec[i].first; 

    return; 
}