【问题标题】:std::replace_if on structure结构上的 std::replace_if
【发布时间】:2012-11-30 14:39:39
【问题描述】:

如果满足条件,我想要做的只是替换结构向量上的一个结构字段。所以这是我的代码:

struct DataST{
    int S_num,Charge,Duplicate_Nu;
    float PEP;
    string PEPTIDE;
    vector<MZIntensityPair> pairs;
    bool GetByT(const DataST& r,int T)
    {
      switch (T)
      {
          case 1:
            return (S_num == r.S_num);
          case 2:
            return (Charge == r.Charge);
          case 3:
            return !(PEPTIDE.compare(r.PEPTIDE));
          case 4:
            return (Duplicate_Nu == r.Duplicate_Nu);
          case 5:
            return ((S_num == r.S_num)&&(Charge == r.Charge));
          default:
            return false;
      }
    }
  };
int main()
{
 .
 .
 vector<DataST> spectrums;
 .
 .
 DataST tempDT_dup;
 tempDT_dup.PEPTIDE="Test";
 replace_if(spectrums.begin(), spectrums.end(), boost::bind(&DataST::GetByT, _1,tempDT_dup,3),11);
 .
 .
}

所以在这个例子中,如果该项目的 PEPTIDE 字段等于“test”,我想用 11 更改所有 Duplicate_Nu 光谱项目,但我在下面出现错误,而我想使用函数 GetByT 而不是操作“=”

/usr/include/c++/4.6/bits/stl_algo.h:4985:4: 错误:'_first 中的 'operator=' 不匹配。_gnu_cxx::__normal_iterator<_iterator _container>::operator* with _Iterator = DataST*, _Container = std::vector, __gnu_cxx::__normal_iterator<_iterator _container>::reference = DataST& = __new_value' /usr/include/c++/4.6/bits/stl_algo.h:4985:4:注意:候选人是: hello_pwiz/hello_pwiz.cpp:14:8: 注意:DataST& DataST::operator=(const DataST&) hello_pwiz/hello_pwiz.cpp:14:8:注意:没有已知的参数 1 从“int DataST::* const”到“const DataST&”的转换

【问题讨论】:

    标签: c++ structure std


    【解决方案1】:

    到目前为止的问题是您试图通过副本传递不可复制的对象。这是因为您作为参数提供给 boost::bind() 的任何内容都将被复制。

    boost::bind(&DataST::GetByT, _1,tempDT_dup,3),
                                     /|\
                                      |
      This means pass by copy. --------
    

    如果您不想通过复制传递,您必须做的是通过指针传递(复制指针不会造成任何伤害)。或者,您可以使用boost::ref 引用传递,例如:

    boost::bind(&DataST::GetByT, _1,boost::ref(tempDT_dup),3),
    

    另一个问题是您将11 指定为std::replace_if() 的最后一个参数。它是一个元素应该被替换的值(如果谓词返回true)。它应该与存储在数组中的对象具有相同的类型(或可转换为)。但是您不能将11(它是一个普通的有符号整数,又名int)转换为DataST 类型的对象。你需要这样的东西:

    vector<DataST> spectrums;
    DataST tempDT_dup;
    DataST replacee; // What you want to replace with...
    replace_if(spectrums.begin(), spectrums.end(),
               bind(&DataST::GetByT, _1, boost::ref(tempDT_dup), 3),
                    replacee);
    

    【讨论】:

    • @khikho:是的,是的,对不起——我已经扩展了答案。
    • UPDATE part 我不能使用 DataST replacee,因为我只想更新 if 谓词返回 true 的结构的 one 字段(在这种情况下我只想更新 Duplicate_Nu)。 [3 是函数 GetByT 的参数,不是替换值]
    • @khikho:那么您只是使用了错误的工具来完成这项工作。如果替换容器内的对象,则替换。即使您可以重载赋值运算符以使其最终工作,但如果我是您,我不会这样做。考虑绑定11,自己检查条件并更新GetByT函数内的内部字段(最好重命名)并将其与std::for_each一起使用。或者干脆在没有这个额外的 mambo-jumbo 的情况下执行它——只需遍历数组即可。它会让你的代码变得更简单、更干净、更容易阅读和理解(对每个人来说)。
    • 您认为这种方法 (for_each) 在非短向量(~1,000,000 个项目)上是否实用(就复杂性而言)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多