代码之家  ›  专栏  ›  技术社区  ›  Alan

从包含在另一个向量类型中的组件构建向量

  •  4
  • Alan  · 技术社区  · 17 年前

    我有一个类似这样的代码:

    struct First
    {
        int f1;
        int f2;
    };
    
    struct Second
    {
        First s1;
        int s2;
    };
    
    std::vector < Second > secondVec;
    
    Second sec;
    sec.s1 = First(); 
    
    secondVec.push_back(sec);
    secondVec.push_back(sec);
    
    std::vector < First > firstVec;
    firstVec.reserve(secondVec.size());
    
    for (std::vector < Second >::iterator secIter = secondVec.begin(); 
             secIter != = secondVec.end();
             ++secIter)
    {
        firstVec.push_back(secIter->s1);
    }
    

    我想把这个丑的换掉 for 使用简单的stl函数进行循环,该函数可能执行等效的过程。我想也许 std::transform 我可以在这里帮助我,但我不确定这是怎么写的。

    如果 促进 这里有什么可以提供的。

    4 回复  |  直到 17 年前
        1
  •  7
  •   Michael Kristofik    17 年前

    如果您有TR1或Boost可用,可以尝试以下操作:

    std::transform(secondVec.begin(),
                   secondVec.end(),
                   std::back_inserter(firstVec),
                   std::tr1::bind(&Second::s1, _1));
    
        2
  •  5
  •   Kirill V. Lyadvinsky    17 年前

    定义将从第二个转换为第一个的函数:

    struct StoF { First operator()( const Second& s ) const { return s.s1; } };
    

    然后按以下方式使用:

    transform( secondVec.begin(), secondVec.end(), back_inserter(firstVec), StoF() );
    

    如果源向量包含很多元素,则应考虑调整目标向量的大小以使其更快地工作,如@goz answer:

    firstVec.resize( secondVec.size() );
    transform( secondVec.begin(), secondVec.end(), firstVec.begin(), StoF() );
    
        3
  •  3
  •   Goz    17 年前

    这并不特别困难…我试过了,没有问题。

    struct First
    {
        int f1;
        int f2;
    };
    
    struct Second
    {
        First s1;
        int s2;
    };
    
    First Replace( Second& sec )
    {
        return sec.s1;
    }
    

    然后用下面的代码复制它

    std::vector < Second > secondVec;
    
    Second sec;
    sec.s1.f1 = 0; 
    sec.s1.f2 = 1; 
    secondVec.push_back(sec);
    
    sec.s1.f1 = 2; 
    sec.s1.f2 = 3; 
    secondVec.push_back(sec);
    
    std::vector < First > firstVec;
    firstVec.resize( secondVec.size() );
    std::transform( secondVec.begin(), secondVec.end(), firstVec.begin(), Replace );
    
        4
  •  2
  •   Gab Royer    17 年前

    你的直觉是对的。虽然您使用的是空向量,但是应该使用 后插入器 对于输出迭代器。

    它看起来应该是类似的:

    std::transform(secondVec.being(), secondVec.end(), back_inserter(firstVec), yourFunctor)
    

    你的导师看起来像这样:

    void youFunctor(First param)
    {
      return param.s1;
    }
    

    编辑:Boost可以帮助您使用lambda函数,因此您不必为此任务创建单独的函数。您还应该注意到lambda函数是Tr1的一部分,将被集成到C++标准库中。

    编辑:这是梅雷迪思和Mem_Fun(或成员函数适配器)的谈话内容。

     struct Second
    {
        First s1;
        int s2;
        First getS1() const {return s1;};
    };
    

    然后转换如下:

    std::transform(secondVec.being(), 
                   secondVec.end(), 
                   std::back_inserter(firstVec), 
                   std::mem_fun(&Second::getS1))