2017-05-03 4 views
1

Ich bin neu in C++ (Ich habe C vor, aber nie C++) Ich glaube, ich habe Syntax-Problem.C++ std :: Liste mit Struktur mit Liste mit Struktur

Ich möchte einige Bestellungen nach Preisniveau in eine Liste sortieren. Also meine Liste Positionen mit innen:

  • das Preisniveau
  • andere std::list mit allen Aufträgen zu diesem Preis. (Aufträge)

Ein Order ist eine Struktur mit:

  • userid
  • quantity

Also habe ich mit endete:

#include<iostream> 
#include<list> 
using namespace std; 

typedef struct Order { 
    int userid; 
    int qty; 
} Order; 

typedef struct Bid { 
    int price; 
    list<Order> Orders; 
} Bid; 

typedef list<Bid> bids; 

int main(void) 
{ 
    bids list; 
    Order order_to_insert; 

    list.begin(); 
    list.front().price = 13000; 

    order_to_insert.userid = 3; 
    order_to_insert.qty = 20; 


    list.front().Orders.begin(); 
    list.front().Orders.front().userid =3; 
    list.front().Orders.front().qty = 20; 
    // list.front().Orders.front() = order_to_insert; // compiles even if i uncomment this. 


    cout << "Liste : " << list.front().price << endl; 
    cout << list.front().Orders.front().qty << endl; 

    return 0; 
}  

die intuitive Art und Weise zunächst war zu Benutzt die kommentierte Zeile, kompiliert sie aber gibt Seg Fehler.

Ich habe kommentiert, um Werte zu Feldern direkt zuzuweisen und es auch Fehler zu segmentieren.

Was ist der richtige Weg, das zu tun?

+1

es verwirrend ist eine Variable nach dem Typ zu nennen - Sie könnten zu ändern 'list', um etwas mehr beschreibend betrachten wollen (wie' bidList' eg.). –

+1

Vermeiden Sie 'namespace std' zu verwenden und insbesondere, wenn Sie' list' als Typ ('std :: list') und als Variablennamen verwenden. – Jarod42

+0

Wenn Sie mit C++ beginnen, könnten Sie an unserer Liste der [guten C++ Bücher] (http://stackoverflow.com/q/388242/1782465) interessiert sein. – Angew

Antwort

5

Zuerst diese Linie list.begin(); und diese Linie list.front().Orders.begin(); nichts tun. Entferne sie.

Jetzt das Hauptproblem. Elemente in Listen erscheinen nicht automatisch. Listen sind leer, wenn sie erstellt werden. Werfen Sie einen Blick auf diese Zeile:

list.front().price = 13000; 

An diesem Punkt Ihre Liste leer ist, gibt es keine .front(). Es ist also ein undefiniertes Verhalten, wahrscheinlich die Ursache für den Segfault.

wird dies tun:

Bid bid; 
list.push_back(bid); 
list.front().price = 13000; 
// or if C++11 
list.emplace_back(); 
list.front().price = 13000; 

Das gleiche gilt für list.front().Orders.front() geht und jede zweite Zeile .front() verwenden.

Seitennotiz: Sie können list.emplace_back statt push_back verwenden. Sie können auch std::vector anstelle von std::list verwenden. Es gibt mehrere Leistungsvorteile gegenüber einer Liste, und es sollte standardmäßig verwendet werden, es sei denn, Sie wissen wirklich, dass Sie Listen benötigen.

+0

Ich benutze Liste, weil ich Elemente einfügen kann, ohne intern alle Präzedenzsätze zu verschieben, und ich muss nicht direkt auf ein Element durch seine Position zugreifen ... (Erhalten Sie das von Scitt Meyer Buch, effektive STL). Lass es mich wissen, bitte. Bitte sag mir, wenn das falsch ist. Danke, für die Antwort, ich versuche es gerade. – jmary

+0

Verwenden Sie 'vector', es sei denn, Sie haben einen guten Grund, einen anderen Container zu verwenden! – Ajay

+0

@jmary Sie können feststellen, dass 'std :: vector' immer noch effizienter ist. Es sei denn, Sie haben mit riesigen Listen zu tun. Sie sagen, Sie werden nicht auf ein Element durch seine Position zugreifen. Werden Sie über die Liste iterieren? Vektoren iterieren waaaaay schneller als Listen (ein Speicherblock, keine Pointer-Dereferenzierung + CPU-Prefetcher). Wie auch immer, messen Sie es. – freakish

1

Der Aufruf von front() auf einer leeren Liste hat ein undefiniertes Verhalten. Eine leere Liste hat kein erstes Element, daher sollten Sie nicht versuchen, darauf zuzugreifen.

Sie können push_back() z. um ein Element in die Liste aufzunehmen, auf das Sie dann zugreifen und es ändern können.

list.push_back(Bid()); 
1

Sie fügen keine Elemente in Ihre Liste ein. std::list::front gibt das erste Element der Liste zurück, wenn es nicht leer ist, aber das Verhalten ist nicht definiert, wenn die Liste leer ist.

std::list::begin gibt einen Iterator an das erste Element zurück, wenn die Liste nicht leer ist, oder einen Iterator für die letzte Stelle, wenn die Liste leer ist.

Verwenden Sie std::list::push_back, um neue Elemente in Ihre Liste einzufügen.

0

Danke Jungs für klare Erklärungen und Ratschläge. ich mit dem folgenden Arbeits Code beendet:

#include <iostream> 
#include <list> 
using namespace std 

typedef struct Order { 
    int userid; 
    int qty; 
} Order; 

typedef struct Bid { 
    int price; 
    list<Order> Orders; 
} Bid; 

typedef list<Bid> bids; 

int main(void) 
{ 
    Bid bid; 
    bids bidList; 
    Order order_to_insert; 

    bidList.push_back(bid); 
    bidList.front().price =13000; 

    order_to_insert.userid = 3; 
    order_to_insert.qty = 20; 

    bidList.front().Orders.push_back(order_to_insert); 
    bidList.front().Orders.front() = order_to_insert; 

    cout << "Liste : " << bidList.front().price << endl; 
    cout << bidList.front().Orders.front().move << endl; 

    return 0; 
} 
+0

Beachten Sie, dass '.push_back (bid);' tatsächlich eine Kopie von 'bid;' erstellt. Um unnötiges Kopieren zu vermeiden, ist '.emplace_back()' bevorzugt. – freakish

+0

Warum push_back (order_to_insert) 'überschreiben Sie das neue Element sofort wieder mit' order_to_insert'? –

+0

Verwenden Sie nicht diese Syntax 'typedef struct T1 {..} T2' in C++. Schreiben Sie einfach 'struct T {..}'. –