Übergeben von std :: vectorint Elementen an Variadic-Funktion

8

Ich benutze gcc 4.6. Angenommen, es gibt einen Vektor v von Parametern, die ich an eine variadische Funktion f übergeben muss (const char * format, ...).

Ein Ansatz dafür ist:

%Vor%

Das Problem ist natürlich, dass es keine willkürliche Anzahl von Elementen in dem Vektor v unterstützt. Ich glaube jedoch verstanden zu haben, wie va_lists im Prinzip funktioniert, d.h. durch Lesen der Argumente von dem Stapel beginnend bei der Adresse des zuletzt genannten Arguments vor "...", Jetzt dachte ich, dass es möglich sein sollte, die Vektorelementwerte in einen Speicherblock (z. B. myMemBlock) zu kopieren. und übergeben Sie die Adresse als zweites Argument nach 'format'. Offensichtlich würde dies erfordern, dass myMemBlock wie erwartet von f () strukturiert wird, d.h. wie ein Stapel.

  1. Ist so etwas machbar?
  2. Alternativ ist es möglich, die Vektor-Item-Werte auf den echten Stack mit Inline-Assembler-Magie zu schieben, Rufen Sie die Funktion f () auf und bereinigen Sie den Stack danach?

Endlich, Dinge, die mir egal sind:

  1. Der Code ist möglicherweise nicht tragbar. OK, ich bin nur an gcc interessiert.
  2. Es könnte andere Ansätze geben, die Preprozessor-Hacker beinhalten.
  3. Die Verwendung der Variadic-Funktion zur Formatierung wie printf () wird für C ++ nicht empfohlen.
  4. Verwendung von variadischen Vorlagenfunktionen.
user1142580 14.02.2012, 12:31
quelle

5 Antworten

2

Okay, hier ist eine Teillösung! Teilweise, weil es nicht für wirklich variadische Funktionen gilt, aber zu denen, die eine va_list als Argument akzeptieren. Aber ich denke, die vollständige Lösung ist nicht weit weg.

Es basiert auf den Beispielen, die ich hier gefunden habe:

  1. Erstellen Sie dynamisch eine va_list Ссылка

  2. Schmiede eine va_list Ссылка

Dieser Code wurde erfolgreich mit gcc unter Linux und VC ++ 2008 getestet. andere Plattformen werden möglicherweise ebenfalls unterstützt, aber das liegt an dir.

Die wichtige Erkenntnis für mich war, dass eine va_list im Grunde nichts anderes ist als ein gepacktes Array, welches mit Daten dynamisch gefüllt werden kann und an Funktionen wie übergeben werden kann vprintf, vfprintf, vsprintf, die es als Argument akzeptieren.

Das Übergeben von Vektorelementen an eine dieser Funktionen kann daher funktionieren, indem genügend Speicher zugewiesen wird für die Vektorelemente und kopieren Sie sie vor dem Aufruf.

Nachdem wir das gesagt haben, ist hier der dynamisch allokierende Stack-Ansatz :

%Vor%

Raten Sie, was es tut? Es ermöglicht die Formatierung von printf (..) mit den in einem Vektor gesammelten Parametern. Ja, es ist nicht perfekt, aber es macht was ich wollte. Darüber hinaus deckt es zwei große Plattformen ab: D

Sehen Sie sich auch diesen Artikel an: va_pass Ссылка

    
user1142580 15.02.2012, 22:08
quelle
3

Unter Ссылка gibt es einen Abschnitt zum Erstellen einer gefälschten va_list. Es ist für Cocoa, aber Sie könnten etwas im Netz für GCC finden.

Ich rate dann würde man so etwas machen:

%Vor%

Aber ich habe absolut keine Ahnung. :)

    
Shadow2531 14.02.2012 13:36
quelle
2

Ihre Reflexion ist nicht auf der richtigen Abstraktionsebene.

Wenn Sie sagen, dass Sie den Vektor in Listen mit variablen Argumenten konvertieren möchten, liegt das daran, dass die Funktion, die die Liste mit den variablen Argumenten übernimmt, Sie interessiert.

Die eigentliche Frage ist also, wie könnte ich dasselbe tun als f , aber ausgehend von einem vector ?

Es ist möglich, dass die Weiterleitung des Aufrufs an f am Ende die Lösung beginnen könnte, aber es ist nicht offensichtlich.

Wenn es nur ums Drucken geht:

%Vor%

Oder, wenn Sie Zugriff auf externe Bibliotheken haben:

%Vor%

An diesem Punkt ist das Interesse von f nicht mehr wirklich offensichtlich.

    
Matthieu M. 14.02.2012 13:51
quelle
1

Nach Ihrer eigenen Antwort zu urteilen, klingt es so, als könnten Sie verwenden Boost-Format .

Beispiele:

%Vor%

Natürlich ist nichts davon notwendig, um einfach einen Vektor auszudrucken.

    
Shadow2531 17.02.2012 15:29
quelle
0

Sie können den STL-Algorithmus für jedes einzelne Element verwenden, um jedes Vektorelement zu drucken.

    
mikithskegg 14.02.2012 12:45
quelle