2012-01-26 24 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; 
}