【问题标题】:c++ STL algo remove_if used with templatec++ STL algo remove_if 与模板一起使用
【发布时间】:2012-01-26 10:20:00
【问题描述】:

我尝试在模板上应用 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>)’

【问题讨论】:

    标签: c++ remove-if


    【解决方案1】:

    您需要更改您对remove_if 的调用,如下所示:

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

    即。在flag_delete 的末尾添加&lt;T&gt;,因为您没有告诉它该函数应该具有与fun_delete_by_flag 相同的模板参数。这里的提示是错误消息末尾的(相当隐藏的)&lt;unresolved overloaded function type&gt;

    【讨论】:

      【解决方案2】:

      无论其他人提出什么观点(需要指定模板参数),您都缺少对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&amp;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;
      }
      

      【讨论】:

        【解决方案3】:

        尝试查看错误信息的第一行:

        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 中定义的参数不同。

        从第一个错误消息中,你给它 pair 。尝试检查您的类型,也许,将 T 更改为另一个字符。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-16
          • 2011-03-22
          • 2010-10-17
          相关资源
          最近更新 更多