【问题标题】:How to compare two consecutive elements in c++ list如何比较c ++列表中的两个连续元素
【发布时间】:2019-07-02 17:41:49
【问题描述】:

我需要找到两个具有相同字段的元素。它们应该在同一个向量中是连续的。我需要用 STL 方法来做。我试过使用 find 或 find_if 但做不到。你能给我任何提示吗?

我的代码(部分代码):

class Sound {
    private:
        int notePitch, length;
    public:
        Sound(int notePitch, int length) {
            this->notePitch = notePitch;
            this->length = length;
        }
        int getPitch() {
            std::cout << "Pitch: " << this->notePitch << " length: " << this->length;
            return this->notePitch;
        }
    };

实际查找功能:

std::vector<Sound>::iterator iter = masterpiece.begin();
std::vector<Sound>::iterator iterEnd = masterpiece.end();   
std::vector<Sound>::iterator it = find_if(iter, iterEnd, [](auto prev, auto next) -> bool {                 
    return prev.getPitch()  == next.getPitch(); 
});

我得到的错误是这样的:

c2678 binary '==' no operator found which takes a left-hand operand of type

【问题讨论】:

  • std::adjacent_find
  • 这是一个奇怪的错误信息。我原以为有两个参数谓词会使这段代码出错。
  • 查找strict weak ordering - 排序时,这是您必须实现的。 return ==return &lt;相同。

标签: c++ algorithm stl find


【解决方案1】:

使用相邻查找代替 find_if。您的代码应该可以工作。

std::vector<Sound>::iterator it = adjacent_find (iter, iterEnd, [](auto prev, auto next) -> bool {                 
    return prev.getPitch()  == next.getPitch(); 

【讨论】:

    【解决方案2】:

    标准算法std::find_if 不接受二元谓词。

    您可以将标准算法 std::adjacent_find 与 lambda 表达式一起使用。

    成员函数getPitch 应使用限定符const 声明。在这种情况下,您可以将函数用于常量对象(例如,当 Sound 类型的对象或对象向量 Sound 被传递给接受常量引用的函数时)

    这是一个演示程序

    #include <iostream>
    #include <vector>
    #include <iterator> 
    #include <algorithm>
    
    class Sound {
        private:
            int notePitch, length;
        public:
            Sound(int notePitch, int length) {
                this->notePitch = notePitch;
                this->length = length;
            }
            int getPitch() const {
    //            std::cout << "Pitch: " << this->notePitch << " length: " << this->length;
                return this->notePitch;
            }
        };
    
    int main( void )
    {
        std::vector<Sound> masterpiece = { { 1, 2 }, { 2, 3 }, { 2, 4 }, { 3, 5 } };
    
        auto it = std::adjacent_find( std::begin( masterpiece ), std::end( masterpiece ),
                                      []( const  Sound &a, const Sound &b )
                                      {
                                        return a.getPitch() == b.getPitch();
                                      } );
    
        if ( it != std::end( masterpiece ) )
        {
            std::cout << "Two adjacent elements are found at position " 
                      << std::distance( std::begin( masterpiece ), it )
                      << '\n';
        }
        else
        {
            std::cout << "Two adjacent elements are found\n";
        }
    }
    

    程序输出是

    Two adjacent elements are found at position 1
    

    你可以使用auto来写lambda表达式的参数

    []( const auto &a, const auto &b )
    {
        return a.getPitch() == b.getPitch();
    }
    

    但无论如何,最好将它们声明为具有 const 引用类型,因为在这种情况下,不会创建临时对象,并且 lambda 表达式保证它不会更改其参数。

    【讨论】:

    • 值得一个简短的说明来解释你为什么constified getPitch。从长远来看,它可能对提问者更有用。
    • @VladfromMoscow 是的。为什么它应该是常量。使用 VC++ 14.x 测试并且能够在没有 const 限定符的情况下进行编译。请提供解释
    • @SolidMercury 您可以不使用 const 进行编译,因为您的向量不是常量,并且您可能将 lambda 表达式的参数声明为非常量引用类型或非引用类型。
    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2019-12-07
    • 2020-07-04
    相关资源
    最近更新 更多