2012-10-19 16 views
5

Mam następującą strukturęporównanie funkcji w dolnej granicy

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

    struct Value { 
     int time; 
     int value; 
     quality qual; 
    }; 

    class MyClass { 

public: 
    MyClass() { 
     InsertValues(); 
    } 

     void InsertValues(); 

     int GetLocationForTime(int time); 

private: 

    vector<Value> valueContainer; 
}; 

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


int MyClass::GetLocationForTime(int time) 
{ 

    // How to use lower bound here. 
    return 0; 
} 

W powyższym kodzie I zostały rzucone z dużą ilością błędów kompilacji. Myślę, że robię źle tutaj Jestem nowy w programowaniu STL i czy możesz mi poprawić gdzie jest błąd? Czy jest lepiej to zrobić?

Dzięki!

+2

Nie otrzymam wszystkich tych głosów do zamknięcia, nie ma nic złego w tym pytaniu. Kod jest nieprawidłowy, ale jest to ważne pytanie. – CashCow

+0

@CashCow - Zgadzam się całkowicie. Mało prawdopodobnym błędem StackOverflow jest działalność nadgorliwych bliskich wyborców. Wraz ze wzrostem liczby użytkowników SO liczba wymaganych głosów bliskich nie * rośnie *, a zamykani wyborcy są bardziej aktywni według zleceń lub rzędów wielkości niż ponownie otwarci wyborcy, powodując ten problem. –

+1

Jeśli problem polega na tym, że ma błędy kompilatora, powinien nam powiedzieć, co to jest. Jeśli widzimy błędy, możemy prawdopodobnie natychmiast wysłać odpowiedź. Bez błędów musimy przejść przez dodatkową pracę polegającą na samodzielnej kompilacji, co sprawia, że ​​nie chcemy odpowiadać, co sprawia, że ​​jest to złe pytanie. –

Odpowiedz

10

Predykat musi przyjąć dwa parametry i zwrócić wartość bool.

Ponieważ funkcja jest funkcją składową, ma nieprawidłową sygnaturę.

Ponadto może być konieczne porównanie wartości do int, wartości do wartości, int do wartości i int do int przy użyciu funktora.

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

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

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

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

To jest dość kłopotliwe, więc niech je zmniejszyć:

struct CompareValueAndTime 
{ 
    int asTime(const Value& v) const // or static 
    { 
     return v.time; 
    } 

    int asTime(int t) const // or static 
    { 
     return t; 
    } 

    template< typename T1, typename T2 > 
    bool operator()(T1 const& t1, T2 const& t2) const 
    { 
     return asTime(t1) < asTime(t2); 
    } 
}; 

następnie:

std::lower_bound(valueContainer.begin(), valueContainer.end(), time, 
    CompareValueAndTime()); 

Istnieje kilka innych błędów też, na przykład nie ma średnika na końcu deklaracji klasy plus fakt, że członkowie klasy są domyślnie prywatni, co powoduje, że cała twoja klasa jest w tym przypadku prywatna. Czy przed konstruktorem spóźniłeś się z public:?

Twoja funkcja GetLocationForTime nie zwraca wartości. Musisz przyjąć wynik lower_bound i odjąć begin() od niego. Funkcja powinna być również stała.

Jeśli intencją tego połączenia jest wstawienie tutaj, należy wziąć pod uwagę fakt, że wstawienie w środku wektora jest operacją O (N), a zatem wektor może być niewłaściwym typem kolekcji tutaj.

Należy pamiętać, że algorytm lower_bound działa tylko w przypadku wstępnie posortowanych kolekcji. Jeśli chcesz, aby móc spojrzeć na poszczególnych członków bez ciągłego uciekania, będziemy chcieli, aby utworzyć indeksy na tych polach, ewentualnie przy użyciu doładowania za multi_index

0

class to słowo kluczowe, a nie "Klasa":

class MyClass { 

A jego ciało powinno być przestrzegane przez średnik ;.
Mogą występować inne błędy, ale może być konieczne wklejenie ich w pytaniu w celu uzyskania dalszej pomocy.

2

Jeden błąd jest to, że czwarty argument do lower_bound (compareValue w kodzie) nie może być funkcją członka. Może to być funktor lub funkcja bezpłatna. Uczynienie z niej darmowej funkcji będącej przyjacielem MyClassa wydaje się najprostsze w twoim przypadku. Poza tym brakuje słowa kluczowego return.

class MyClass { 
    MyClass() { InsertValues(); } 
    void InsertValues(); 
    int GetLocationForTime(int time); 
    friend bool compareValue(const Value& lhs, const Value& rhs) 
    { 
     return lhs.time < rhs.time; 
    } 
0

Po prostu chcesz, aby compareValue() była normalną funkcją. Sposób, w jaki go wdrożyłeś już teraz, wymaga obiektu typu MyClass wokół. Sposób, w jaki std::lower_bound() spróbuje go wywołać, po prostu przekazuje dwa argumenty, bez dodatkowego obiektu. Jeśli naprawdę chcesz, aby funkcja była członkiem, możesz ustawić ją jako członka static.

Powiedziawszy, istnieje kara za wydajność za korzystanie z funkcji bezpośrednio. Może chcesz mieć rodzaj komparatora z operatorem połączeń inline funkcji:

struct MyClassComparator { 
    bool operator()(MyClass const& m0, MyClass const& m1) const { 
     return m0.time < m1.time; 
    } 
}; 

... MyClassComparator() i używać jako komparatora.

2
  1. Class słowa kluczowego musi zacząć od niższych c - class.
  2. struct Value ma niewłaściwy typ qualtiy zamiast quality
  3. Nie widzę using namespace std używać typów STL bez niego.
  4. vector<value> - niewłaściwy typ value zamiast Value
  5. Etc.

Musisz go najpierw sprawdzić przed wysłaniem tutaj z takich prostych błędów myślę. I główny problem tutaj, że funkcja porównania nie może być członkiem klasy. Użyj go jako funkcji bezpłatnej:

bool compareValue(const Value lhs, const int time) { 
    return lhs.time < time ; 
} 
+0

Naprawiłem kilka literówek, założyłem, że użył std przestrzeni nazw; i zawiera odpowiednie nagłówki. (Oczywiście lepiej zakwalifikować niż używać przestrzeni nazw). – CashCow