C++ Variable Typen der Funktions-Parameter

Crazy Driver

Ensign
Registriert
Jan. 2011
Beiträge
182
Hallo,

Gibt es eine Möglichkeit die Typen der Paramter der Funtionen variabler zu gestalten?
Mein Beispiel wird es hoffentlich verständlich machen ;):
PHP:
#include <iostream>

using namespace std;

void clear(char *my_array) // Eine einfache Funktion um einen Array zu leeren
{
    my_array[0] = 0;
}

int main()
{
    char char_string[] = "Hallo!";
    int int_string[] = {1,2,3,4,5,6,7,8,9,0};

    clear(char_string);
    clear(int_string); // FEHLER!

    return 0;
}
Da int_string vom Typ int ist, kann die Funktion clear damit nicht arbeiten!

Ich wüsste also gerne, ob es eine flexible möglichkeit für das Problem gibt.
Ich habe nämlich keine Lust die gleiche Funktion für int, double, sowohl in Kombination
mit signed und unsigned zu schreiben.
 
Mal abgesehen davon das dein clear garnichts leert ausser dem ersten Element des Arrays wäre das Problem durch Überladen bzw Templates erschlagbar.
 
Code:
template<class T> inline void clear(T*& p)
{
	if (p)
	{
		p[0] = 0;
	}
}
 
4cc schrieb:
Mal abgesehen davon das dein clear garnichts leert ausser dem ersten Element des Arrays wäre das Problem durch Überladen bzw Templates erschlagbar.

Also bei mir wird alles geleert! Alternativ könnte man es auch so machen!
PHP:
void clear(char *my_array)
{
       for(int = 0; i <= 10 ++i)
       {
            my_array[i] = 0;
       }
}
 
Natürlich ist der String dann "leer", weil C-Strings nullterminiert sind.
Die nachfolgenden Elemente sind natürlich unverändert.

Code:
void clear(char *my_array)
{
       for(int = 0; i <= 10 ++i)
       {
            my_array[i] = 0;
       }
}
Das ist hervorragendes Code... hervorragend, wenn es darum geht, fehleranfällige Programmezu schreiben.

du solltest zwingend einen zweiten Paramter für die Array-Größe dazu machen...
Zudem seh ich hier wenig Sinn in den Templates, da ein clear bei einem C-String nun mal anders arbeiten kann wie bei einem int-Array... würde hier überladene Funktionen vorziehen...
 
Das ist hervorragendes Code... hervorragend, wenn es darum geht, fehleranfällige Programmezu schreiben.
Besser :D:
PHP:
void string_clear(char *my_array, long max)
{
    for(long i = 0; i <= max - 1; ++i)
    {
        clear_var[i] = 0;
    }
}
 
Öhm...
Code:
memset( &char_string, 0, 10 );
memset( &int_string, 0, 10 );
?!

edit: Denkfehler... :/
 
Wieso "i <= max - 1" anstatt einfach "i < max"

Und Yuuri, geht natürlich auch. Wobei es beim C-String gar nicht so aufwändig sein muss... je nach Anforderung.
Aber... wie sieht es bei double aus? Ist ein double mit dem Bitmuster 0 auch wirklich 0?
 
Crazy Driver schrieb:

Er meint wohl eher sowas:
Code:
void string_clear(char *my_array)
{
    for(long i = 0; i <= sizeof(array) / sizeof(array[0]); ++i)
    {
        clear_var[i] = 0;
    }
(keine Ahnung ob das so stimmt, hab nur kurz gegooglet)
 
@locomarco: Nein, das war schon so gemeint, das Problem ist, dass sich die Größe eines Arrays nicht immer in C abfragen lässt...

@Crazy Driver: Was ist denn das Thema?
Dir wurden zwei Wege genannt:
- Templates
- Überladen von Funktionen

Ohne zu wissen, warum du das alles brauchst, kann mann dir auch keine wirkliche Empfehlung geben. Eventuell reicht ja auch ein memset, eventuell auch nicht...
 
Also im Grunde bei der Vielfalt würde ich wohl ne Kombination aus beidem nehmen...
 
Nimm void* und arbeite damit. Außerdem memset().
Dann gibt es natürlich noch vararg Kram, wenn du das machen willst. Das ist aber deutlich komplizierter.
 
klar kann man es mit void* und memset machen.
aber das hilft halt bei diesem einen fall aber nicht bei der grundlegenden Frage: Wie macht man sowas?
 
asdfman schrieb:
Nimm void* und arbeite damit. Außerdem memset().
Dann gibt es natürlich noch vararg Kram, wenn du das machen willst. Das ist aber deutlich komplizierter.

Das wäre vielleicht für C eine hinnehmbare Lösung. Da zumindest der Thread als C++ ausgewiesen ist, kann ich nur sagen, Finger weg von void* und memset. Bei PODs mag das ja noch definiert sein, aber danach wird es hässlich und undefiniert.

Überladen oder ein (Funktions-)Template sind eine adäquate Wahl. (auf keinen Fall eine Funktionstemplate überladen oder spezialisieren)

Oder einfach mit vector und string arbeiten.
 
Spontan würde ich den Code STL-like so schreiben:
Code:
template<typename iterator> struct Cleaner
{
   void operator()(iterator begin, iterator end) const
   {
      for (iterator i = begin; i != end; ++i)
       *i = 0;
   }
};

template<typename iterator> void clean(iterator begin,iterator end)
{
  Cleaner<iterator>()(begin,end);
}
Wenn es Spezialfälle gibt dann einfach das Cleaner-template spezialisieren.

EDIT: Um das noch zu erklären: Function-Templates schließen ihren Typ aus ihren Parametern, daher sind sie einfach zu benutzen, können aber nicht wirklich spezialisiert werden, sondern nur überladen. Mit einer struct oder class. was bekanntlich das Gleiche ist, hat man bei der Spezialisierung die freie Wahl der Waffen.
 
Zuletzt bearbeitet:
@ghorst: Das Gleiche, abgesehen von der Standard-Sichtbarkeiten... ;-)
 
ich hab von c++ nicht viel ahnung aber in C selber habe ich um von einem Char array die länge zu ermitteln, einfach immer eine einzeilige for-schleife durchlaufen lassen um quasi die länge des Arras zu bekommen:

Code:
int ptrfunk(char *str)
{
     int length;

     for(length= 0, str; *str != "\0"; length++, str++);
     // Danach hast du im prinzip die länge deines Arrays als integer wert ;-)

   return length;
}

So lange dein Code sich nicht auf mehrer Datentypen ausweitet und es nur um den Zweck in einem Programm geht, würde ich auch die Überladung anwenden.

Gruß Ali.
 
Zuletzt bearbeitet:
Zurück
Oben