Gibt es eine sinnvolle Verwendung einer Funktion, die eine anonyme Struktur zurückgibt?

7

Hier ist ein (künstliches) Beispiel für die Verwendung einer Funktion, die eine anonyme Struktur zurückgibt und "etwas" nützlich macht:

%Vor%

Es gibt ein paar Punkte, die ich gerne diskutieren würde:

  1. Wie offenkundig, leckt dieser Code, gibt es trotzdem, ich kann nicht lecken, ohne zu wissen, was die zugrunde liegende Strukturdefinition ist? siehe Kommentar [1].
  2. Ich muss einen Zeiger auf eine anonyme Struktur zurückgeben, damit ich eine Instanz des Objekts innerhalb der Template-Funktion func erstellen kann, kann ich etwas Ähnliches tun, ohne einen Zeiger zurückzugeben?
  3. Ich denke, das Wichtigste, gibt es JEDEN (realen) Gebrauch dafür überhaupt? Wie das oben genannte Beispiel leckt und zugegebenermaßen erfunden ist.

Übrigens, was die Funktion foo(a,b) tut, ist, eine Struktur zurückzugeben, die zwei Zahlen enthält, die Summe aller Zahlen von 1 bis a und das Produkt von a und b.

Vielleicht könnte die Zeile new T irgendwie boost :: shared_ptr verwenden, um Lecks zu vermeiden, aber ich habe das nicht versucht. Funktioniert das?

Ich glaube, ich habe gerade versucht, die anonyme Struktur als ein Array von Schwimmern zu löschen, etwas wie float * f = new float [2]. Was könnte falsch sein, wie der Kommentar unten suggeriert, also was kann getan werden? kann ich überhaupt löschen?

Ich kann diesen Code "wie besehen" auf VS2008 kompilieren und ausführen, vielleicht werden einige Nicht-Standard-Erweiterungen von VS verwendet, aber es läuft und gibt 15 und 30 als Antwort.

Von den Antworten glaube ich, dass diese Vorrichtung eine VS2008-spezifische Einheit ist, nicht standardkonform und daher nicht tragbar. Zu schade, aber ich hätte gerne gesehen, was Voodoo die Stackoverflow oder Boost Leute ausdachten, wenn dies in ihrem Arsenal war :). Danke allen.

    
Akanksh 08.04.2010, 07:18
quelle

5 Antworten

9

Momentan ist Ihr Code nicht tragbar. Es wird zum Beispiel nicht mit gcc erstellt.

In Abschnitt 14.3.1 / 2 des Standards heißt es:

  

Ein lokaler Typ, ein Typ mit keiner   Verknüpfung, ein unbenannter Typ oder ein Typ
  zusammengesetzt von irgendwelchen von diesen Arten    darf nicht als Vorlage verwendet werden   Argument für eine Vorlage   Typ-Parameter.

Siehe Punkt 488 in den C ++ Standard-Kernsprachdefekt-Berichten, Revision 69 und Paper N2657 für eine mögliche Entwicklung.

UPDATE 1

Angenommen, Ihr Code wäre wohlgeformt, dann:

  1. können Sie vielleicht neu schreiben:

    %Vor%

    als

    %Vor%
  2. Sie können einen anonymen struct by-Wert zurückgeben, vorausgesetzt, die anonyme Struktur hatte einen Konstruktor, der einen anderen Typ angenommen hat (anonym oder nicht, den Sie im Körper Ihrer Methode initialisieren könnten) - außer natürlich, wie spezifiziert man einen Konstruktor für eine anonyme Struktur? :)

  3. keine reale Verwendung, die ich anders sehen kann als eine extrem verschlungene Art zu versuchen, der Struktur keinen expliziten Namen zu geben; Man würde typischerweise anonyme Strukturen verwenden (technisch nicht legal in C ++, aber von verschiedenen Compilern als Erweiterungen unterstützt), um den Namespace nicht zu verunreinigen, typischerweise indem man ihn sofort instanziiert (man kann zum Beispiel instanziierte und vererbte One-Shot-Funktoren sehen) als anonyme Strukturen - wieder, technisch nicht legal C ++.)

AKTUALISIEREN 2

Danke gf für die Verknüpfung mit dem relevanten Teil des C ++ - Standards bezüglich neuer Typen, die möglicherweise nicht in einem Rückgabetyp definiert sind.

UPDATE 3

Dies hier aus den Kommentaren herausholen: Aufruf von delete[] für Speicher, der mit new (im Gegensatz zu new[] ) belegt ist, ist eine Einladung zum Heap-Fehler. Aufruf von delete für einen Zeiger, dessen Typ nicht bekannt ist, ist technisch undefiniert (welcher Destruktor sollte aufgerufen werden?), Aber im Fall von PODs (Ihre anonyme Struktur ist eine) können Sie damit in diesem schrecklichen hackischer Weg:

%Vor%

Wenn Ihr Code magisch wohlgeformt wäre, wäre std::auto_ptr in der Lage gewesen, den anonymen Typ zu behalten und hätte dafür gesorgt, dass Sie delete korrekt und anmutig aufrufen.

    
vladr 08.04.2010, 07:39
quelle
5

Was Sie tun, ist in Standard C ++ nicht möglich - Typdefinitionen sind in Rückgabetypen gemäß §8.3.5 / 6 (Funktionsdeklaratoren, C ++ 03) nicht erlaubt:

  

Typen dürfen nicht in Rückgabe- oder Parametertypen definiert werden.

Visual Studio ist in diesem Fall nicht kompatibel.

    
Georg Fritzsche 08.04.2010 07:48
quelle
3

C ++ Standard erlaubt keine anonymen Strukturen.

    
Kirill V. Lyadvinsky 08.04.2010 07:40
quelle
1

Ich kann mir keine vernünftige Verwendung vorstellen. Abgesehen von den Speicherlecks ist dies eine sehr unlesbare Möglichkeit, das gewünschte Ziel zu erreichen. Es lässt Ihren Leser viel darüber nachdenken, was der Code tut. Und es ist auch nicht bekannt, wer 'f' im main () löschen soll. Und sollte es mit delete [] oder delete gelöscht werden?

Ich würde eine Klasse verwenden, die das 'a' und 'b' im Konstruktor verwendet. Es wird zwei Methoden zum Abrufen der zwei berechneten Strukturelemente haben. Und innerhalb der Klasse wird es private mehotds geben, die einfache Schleifen verwenden, um die Dinge zu berechnen, die Sie wollen. Dann wird Ihre API wie folgt aussehen:

%Vor%     
m_pGladiator 08.04.2010 07:40
quelle
1

Eine enge Annäherung an eine anonyme Struktur ist ein Tupel. Boost :: Tuple ist jetzt überall verfügbar, und es gibt noch einen anderen in TR1 [von dem ich annehme, ist mit VS2008 verteilt] mit einer nahezu identischen Schnittstelle.

%Vor%

Wie andere gesagt haben, ist das Gesamtschema ziemlich schwach, aber ich wollte mich eher auf das Tupel als auf das Design konzentrieren.

    
Dennis Zickefoose 08.04.2010 07:57
quelle