Forum: PC-Programmierung c++, STL Grundlagen. Konkrete Frage


von lerner (Gast)


Lesenswert?

Hallo ich habe folgende Frage. Es steht im Grunde als Kommentar im Code.
Bei mir steht der Versuch ins Haus nach 15 Jahren c auf c++ zu 
erweitern.

Die Lernkurve wird glaube ich unterschätzt wenn man von Objekten und der 
ganzen Denkweise nicht beherrscht wird. Ich glaube das ganze wirkt so 
mächtig, dass man auch gut mal zu viel erhofft. Vielleicht geht es mir 
grad so.
Dazu neue Syntax, neue Bibliotheken... Dennoch werde ich es wagen und 
frage mal ganz einfach heraus, wer Rat weiß.
1
#include <iostream>
2
#include <vector>
3
#include <deque>
4
#include <algorithm>
5
6
7
//Fragen:
8
//Kann man PrintIntVector so umschreiben, dass es ein PrintIntContainer ist, also merkt wenn es z.B. ein deque wäre?
9
//Kann man PrintIntVector (oder PrintIntContainer) so schreiben, dass es auch für double oder andere Typen geht?
10
//Oder wie würde das gehen. eine Print Klasse mit überladenen Funktionen wäre ja nicht universiell
11
static void PrintIntVector( std::vector<int> &cont )
12
{
13
    for( std::vector<int>::iterator cont_it =cont.begin(); cont_it != cont.end(); cont_it++)
14
    {
15
        std::cout << *cont_it << " ";
16
    }
17
    std::cout << std::endl;
18
}
19
20
int main()
21
{
22
    std::vector<int> cont;
23
24
    std::vector<double> cont2;       //So wenn ich da jetzt was reinlege und auch über eine Print Funktion ausgeben möchte?
25
    //std_vector<my_class> cont3;    //Oder gar da?? Geht das überhaupt?
26
    std::deque<int> cont4;           //Sogar ints...gibt es da eine universielle Methode für ein PrintWhatIwant?
27
28
29
//Container füllen
30
    for(int n=0; n<20; n++) {
31
        cont.push_back(n);
32
33
        cont4.push_back(n);         //Kann ja SO jetzt nicht einfach peglottet werden
34
        cont2.push_back( (double)n );
35
    }
36
    PrintIntVector(cont); //Oder lieber PrintVector() oder noch lieber PrintContainer....
37
38
//durcheinander bringen
39
    std::random_shuffle(cont.begin(), cont.end());
40
    PrintIntVector(cont);
41
42
//wieder sortieren
43
    std::sort(cont.begin(), cont.end());
44
    PrintIntVector(cont);
45
46
    return 0;
47
}

von J. Eder (Gast)


Lesenswert?

Ich würde es mal über ein Funktionstemplate probieren
(Hier gibt es eine gute Beschreibung dazu: 
www.cpp-tutor.de/cpp/le15/funk_templ.html)

von Tom (Gast)


Lesenswert?

>[function templates]
Dann wirst Du für den Iterator das hier brauchen:
http://en.wikipedia.org/wiki/Typename#A_method_for_indicating_that_a_dependent_name_is_a_type

>   //std_vector<my_class> cont3;    //Oder gar da?? Geht das überhaupt?
Ja. http://msdn.microsoft.com/de-de/library/1z2f6c2k.aspx


Falls du C++11 benutzen kannst, sieh dir auch range based for loops 
statt iterator an.

von nicht"Gast" (Gast)


Lesenswert?

moin

probier mal

1
template<class T>
2
void Print(const T &toPrint){    
3
  std::copy(toPrint.begin(), toPrint.end(),std::ostream_iterator<T::value_type>(std::cout, " " ));
4
  std::cout << "\n";
5
}

braucht noch #include <iterator>


Grüße,

von Rolf M. (rmagnus)


Lesenswert?

lerner schrieb:
> //Fragen:
> //Kann man PrintIntVector so umschreiben, dass es ein PrintIntContainer
> ist, also merkt wenn es z.B. ein deque wäre?
> //Kann man PrintIntVector (oder PrintIntContainer) so schreiben, dass es
> auch für double oder andere Typen geht?

Beides läßt sich machen, indem man aus der Funktion ein Template macht.
Übrigens: Da du den Container in der Funktion nicht änderst, sollte die 
Referenz darauf const sein und mit einem const_iterator durchlaufen 
werden. In C wird const sehr lax gehandhabt. In C++ ist das anders, 
daher solltest du immer auf const-korrekte Programmierung achten, d.h. 
alles const machen, was nicht verändert wird.

So würde die Funktion als Template aussehen: (ungetestet)

[C]
template <typename Container>
void PrintContainer(const Container& cont)
{
    for(Container::const_iterator cont_it =cont.begin(); cont_it != 
cont.end(); cont_it++)
    {
        std::cout << *cont_it << " ";
    }
    std::cout << std::endl;
}

>     std::vector<double> cont2;       //So wenn ich da jetzt was reinlege
> und auch über eine Print Funktion ausgeben möchte?
>     //std_vector<my_class> cont3;    //Oder gar da?? Geht das überhaupt?

Ja das geht, wenn du für my_class einen operator<< definierst, in dem 
festgelegt wird, wie dein Objekt ausgegeben werden soll.

von Klaus W. (mfgkw)


Lesenswert?

1
template< class CONTAINER >
2
void PrintWhatIWant( const CONTAINER &cont )
3
{
4
  for( typename CONTAINER::const_iterator iCont=cont.begin(); iCont!=cont.end(); ++iCont )
5
  {
6
    std::cout << (*iCont) << " ";
7
  }
8
  std::cout << std::endl;
9
}
Das ist i.W. der Vorschlag von Rolf Magnus, aber er funktioniert (dank 
des typename in der for-Schleife).

von Rolf M. (rmagnus)


Lesenswert?

Ah richtig. Dependant types... da hatte ich nicht dran gedacht.

von Plauzi (Gast)


Lesenswert?

1
template< class CONTAINER >
2
void PrintWhatIWant(const CONTAINER &cont)
3
{
4
  for(auto iCont = begin(cont); iCont != end(cont); ++iCont) {
5
    std::cout << (*iCont) << " ";
6
  }
7
  
8
  std::cout << std::endl;
9
}

von Rolf M. (rmagnus)


Lesenswert?

Übrigens:

> CONTAINER

würde ich nicht als Name für den Template-Parameter verwenden, da 
komplett groß geschriebene Namen üblicherweise für Makros reserviert 
werden.

Plauzi schrieb:
> template< class CONTAINER >
> void PrintWhatIWant(const CONTAINER &cont)
> {
>   for(auto iCont = begin(cont); iCont != end(cont); ++iCont) {
>     std::cout << (*iCont) << " ";
>   }
>
>   std::cout << std::endl;
> }

Wenn schon C++11, dann kann man auch gleich noch einen Schritt weiter 
gehen:
1
template<class Container>
2
void PrintWhatIWant(const Container& cont)
3
{
4
    for(const auto& element: cont)
5
    {
6
        std::cout << element << " ";
7
    }
8
    std::cout << std::endl;
9
}

von Klaus W. (mfgkw)


Lesenswert?

Rolf Magnus schrieb:
> Übrigens:
>
>> CONTAINER
>
> würde ich nicht als Name für den Template-Parameter verwenden, da
> komplett groß geschriebene Namen üblicherweise für Makros reserviert
> werden.

naja, der gängigste Nme für Templateparameter ist T ...

von lerner (Gast)


Lesenswert?

Einen herzlichen Dank erst mal an alle.
Ich hoffe ich finde am Wochenende etwas Zeit um mir eure posts zu 
verinnerlichen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.