1

上界と下界の呼び出しでクラッシュした次のプログラムがあります。クラッシュが発生する理由がわかりません。私がクラッシュしている理由。あなたの助けと時間をありがとう。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

enum quality { good = 0, bad, uncertain };

struct sValue {
   int time;
   int value;
   int qual;
};

struct CompareLowerBoundValueAndTime { 
    bool operator()( const sValue& v, int time ) const {
        return v.time < time;
    } 

    bool operator()( const sValue& v1, const sValue& v2 ) const { 
        return v1.time < v2.time; 
    }

    bool operator()( int time1, int time2 ) const { 
        return time1 < time2; 
    }   

    bool operator()( int time, const sValue& v ) const  { 
        return time < v.time;    
    } 
}; 

struct CompareUpperBoundValueAndTime { 
    bool operator()( const sValue& v, int time ) const {
        return v.time > time;
    } 

    bool operator()( const sValue& v1, const sValue& v2 ) const { 
        return v1.time > v2.time; 
    }

    bool operator()( int time1, int time2 ) const { 
        return time1 > time2; 
    }   

    bool operator()( int time, const sValue& v ) const  { 
        return time > v.time;    
    } 
}; 

class MyClass {

public:
    MyClass() {
        InsertValues();
    }

       void InsertValues();

       int GetLocationForTime(int time);

       void PrintValueContainer();

private:

    vector<sValue> valueContainer;
};

void MyClass::InsertValues() {
    for(int num = 0; num < 5; num++) {
        sValue temp;
        temp.time = num;
        temp.value = num+1;
        temp.qual = num % 2;
        valueContainer.push_back(temp);
    }
}

void MyClass::PrintValueContainer()
{
    for(int i = 0; i < valueContainer.size(); i++) {
        std::cout << i << ". " << valueContainer[i].time << std::endl;
    }
}




int MyClass::GetLocationForTime(int time)
{
    std::vector< sValue >::iterator lower, upper;
    lower =  std::lower_bound(valueContainer.begin(), valueContainer.end(), time, CompareLowerBoundValueAndTime() );

    upper =  std::upper_bound(valueContainer.begin(), valueContainer.end(), time, CompareUpperBoundValueAndTime() ); // Crashing here.

    std::cout << "Lower bound: " << lower - valueContainer.begin() << std::endl;
    std::cout << "Upper bound: " << upper - valueContainer.begin() << std::endl;

   return lower - valueContainer.begin();
}



int main()
{
    MyClass a;
    a.PrintValueContainer();
    std::cout << "Location received for 2: "  << a.GetLocationForTime(2) << std::endl;
    return 0;
}
4

4 に答える 4

8

lower_boundupper_boundソートされたシーケンスで作業します。シーケンスは、両方の関数に渡す同じ比較関数を使用して並べ替える必要があります。

要素を挿入するときはInsertValues、昇順で挿入するので、CompareLowerBoundValueAndTimeを比較する正しい方法です。

しかし、upper_boundあなたは別の比較関数を渡しているのです。合格CompareLowerBoundValueAndTime()すれば動作するはずです。

CompareLowerBoundValueAndTimeこれは誤解を招く名前であることに注意してください。の線に沿ったものでなければなりませんCompareValueAndTimeAscending

于 2012-10-19T08:48:53.930 に答える
1

上界と下界の両方に同じ比較子を使用する必要があります。違いは、比較ではなく、アルゴリズムにあります。

于 2012-10-19T08:49:02.483 に答える
1

あなたのコンパイラはあなたに答えを与えています。ここでコードを確認してください:http://ideone.com/x6RE9

これにより、次のようなエラーが発生します。

prog.cpp: In member function ‘int MyClass::GetLocationForTime(int)’:
prog.cpp:94: error: no match for ‘operator*’ in ‘*upper.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = sValue*, _Container = std::vector<sValue, std::allocator<sValue> >]()’

2回逆参照する必要はありupperません、それは意味がありません。

于 2012-10-19T08:49:07.837 に答える
0

シーケンスが正しくソートされていないことが検出されたため、upper_boundでアサーションエラーが発生していると思います。

あなたはupper_boundが何をするのか誤解しているようです。これは、イテレータが指す項目が検索値よりも厳密に大きくなり、それ以上ではないことを除いて、lower_boundと同じです。そのような値がない場合は、シーケンスの最後を指します。

述語(Pred)を使用する場合は、次のようにソートする必要があります。

 Pred( iter2, iter1 )

iter2がシーケンス内でiter1よりも後に表示される場合は常にfalseを返します。

これは、シーケンスと述語の組み合わせには当てはまらないため、アサーションエラーが発生します。

于 2012-10-19T08:58:02.553 に答える