Verhindern Array-Zerfall in Parameter-Pack-Erweiterung

8

Ist es möglich, das Verwerfen von Array zu Pointer in Argumenten zu verhindern, die von einem Parameterpaket erweitert wurden?

Zum Beispiel:

%Vor%

... Ausgänge:

%Vor%

Wie Sie sehen, geht der erste Aufruf an die Array-basierte Überladung, aber nachfolgende Aufrufe gehen an die zeigerbasierte Überladung. Gibt es eine Möglichkeit, alle Aufrufe an die Array-basierte Überladung zu senden?

Related: Probleme spezialisierte Variable Template-Funktion

    
Nate Kohl 17.12.2012, 21:02
quelle

2 Antworten

7

Sie möchten das Parameterpaket nach rvalue-Referenz übergeben:

%Vor%

Der Code sieht also folgendermaßen aus:

%Vor%

Geben Sie das Ergebnis:

%Vor%

Ich habe die anderen Überladungen nicht geändert, um das Gleiche zu tun, aber normalerweise sollten sie auch eine rvalue-Referenz verwenden (wenn sie tatsächlich verwendet wurden).

Bearbeiten: Warum sollten Sie das tun / warum es funktioniert: Eine rvalue-Referenz kann entweder an einen rvalue oder an einen lvalue binden. Der entscheidende Punkt, den wir hier beachten, ist, dass wenn er an einen L-Wert bindet, er ein L-Wert bleibt. Im Fall eines Arrays behält es seine Identität als ein Array bei, so dass ein Array empfangen wird.

Wenn / wenn wir ein Array nach Wert übergeben, erfährt es den normalen "Zerfall" in einen Zeiger, genau wie bei einer normalen Funktion.

Für diesen speziellen Fall könnten wir auch eine normale L-Wert-Referenz verwenden - aber wenn wir das täten, würde das nicht für irgendeinen Typ funktionieren, der kein L-Wert ist. Wenn wir beispielsweise versuchen, foo(1,2,3); aufzurufen, erhalten wir einen Fehler, weil eine Lvalue-Referenz nicht an 1 , 2 oder 3 gebunden werden kann. Um damit umzugehen, könnten wir eine const lvalue-Referenz übergeben, aber dann würden wir die Referenz nicht direkt an den rvalue binden - wir würden ein temporäres erstellen, das eine Kopie des rvalue enthält das wurde übergeben, und binden Sie stattdessen die Lvalue-Referenz auf diese temporäre Kopie. Für den speziellen Fall eines int wäre das wahrscheinlich kein großes Problem, aber mit etwas, das teurer zu kopieren war (oder wenn wir Zugriff auf das Original, nicht eine Kopie haben wollten), könnte das ein Problem sein.

>     
Jerry Coffin 17.12.2012, 21:13
quelle
5

@ JerryCoffins Antwort traf bereits die Stelle, aber ich wollte eine kleine Bemerkung hinzufügen. Sie können den Listenverarbeitungscode vom folgenden Element trennen:

%Vor%

(Vielleicht gibt es schon ein Idiom dafür?).

    
didierc 17.12.2012 21:39
quelle

Tags und Links